通过这一节的学习,你可以在UI界面做监测终端信息,如CPU 时间等各类系统参数,狂拽酷炫吊炸天
目录
获取进程时间
系统基本参数
#include <sys/utsname.h>int uname(struct utsname *buf);buf : struct utsname 结构体类型指针,指向一个 struct utsname 结构体类型对象。返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno 。
struct utsname {
char sysname[]; /* 当前操作系统的名称 */
char nodename[]; /* 网络上的名称(主机名) */
char release[]; /* 操作系统内核版本 */
char version[]; /* 操作系统发行版本 */
char machine[]; /* 硬件架构类型 */
#ifdef _GNU_SOURCE
char domainname[];/* 当前域名 */
#endif
};
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
int main(void) {
struct utsname os_info;
int ret;
/* 获取信息 */
ret = uname(&os_info);
if (-1 == ret) {
perror("uname error");
exit(-1);
}
/* 打印信息 */
printf("操作系统名称: %s\n", os_info.sysname);
printf("主机名: %s\n", os_info.nodename);
printf("内核版本: %s\n", os_info.release);
printf("发行版本: %s\n", os_info.version);
printf("硬件架构: %s\n", os_info.machine);
exit(0);
}
sysinfo 函数(可用内存和进程)需要定义一个 struct sysinfo 结构体变量
#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);info : struct sysinfo 结构体类型指针,指向一个 struct sysinfo 结构体类型对象。返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno 。
struct sysinfo {
long uptime; /* 自系统启动之后所经过的时间(以秒为单位) */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* 总的可用内存大小 */
unsigned long freeram; /* 还未被使用的内存大小 */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* 系统当前进程数量 */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* 内存单元大小(以字节为单位) */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
int main(void) {
struct sysinfo sys_info;
int ret;
/* 获取信息 */
ret = sysinfo(&sys_info);
if (-1 == ret) {
perror("sysinfo error");
exit(-1);
}
/* 打印信息 */
printf("uptime: %ld\n", sys_info.uptime);
printf("totalram: %lu\n", sys_info.totalram);
printf("freeram: %lu\n", sys_info.freeram);
printf("procs: %u\n", sys_info.procs);
exit(0);
}
#include <unistd.h>int gethostname(char *name, size_t len);指向用于存放主机名字符串的缓冲区。len : 缓冲区长度。返回值: 成功返回 0, ;失败将返回 -1 ,并会设置 errno 。
#include <unistd.h>long sysconf(int name)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
printf("每个用户的最大并发进程数: %ld\n", sysconf(_SC_CHILD_MAX));
printf("系统节拍率: %ld\n", sysconf(_SC_CLK_TCK));
printf("系统页大小: %ld\n", sysconf(_SC_PAGESIZE));
exit(0);
}
时间、日期(GMT、UTC、时区)
#include <time.h>time_t time(time_t *tloc);tloc : 如果 tloc 参数不是 NULL ,则返回值也存储在 tloc 指向的内存中。返回值: 成功则返回自 1970-01-01 00:00:00 +0000 (UTC) 以来的时间值(以秒为单位);失败则返回 -1 , 并会设置 errno 。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
time_t t;
t = time(NULL);
if (-1 == t) {
perror("time error");
exit(-1);
}
printf("时间值: %ld\n", t);
exit(0);
}
gettimeofday 函数
#include <sys/time.h>int gettimeofday(struct timeval *tv, struct timezone *tz);tv : 参数 tv 是一个 struct timeval 结构体指针变量tz : 参数 tz 是个历史产物,早期实现用其来获取系统的时区信息,目前已遭废弃,在调用 gettimeofday() 函数时应将参数 tz 设置为 NULL 。返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno 。
time函数与gettimeofday函数,获得的均是时间段值,因此需要转换为具体的时间。
#include <time.h>char *ctime(const time_t *timep);char *ctime_r(const time_t *timep, char *buf);timep : time_t 时间变量指针。返回值: 成功将返回一个 char * 类型指针,指向转换后得到的字符串;失败将返回 NULL
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
char tm_str[100] = {0};
time_t tm;
/* 获取时间 */
tm = time(NULL);
if (-1 == tm) {
perror("time error");
exit(-1);
}
/* 将时间转换为字符串形式
从tm转至tm_str
*/
ctime_r(&tm, tm_str);
/* 打印输出 */
printf("当前时间: %s", tm_str);
exit(0);
}
//当前时间:Mon Feb 22 17:10:46 2021 (字符串形式)
localtime 函数(变成struct tm 结构体所表示的时间)(本地时间)
(注意使用时要使用可重入版本 localtime_r(),而不是不可重入版本localtime())
#include <time.h>struct tm *localtime(const time_t *timep);struct tm *localtime_r(const time_t *timep, struct tm *result);timep : 需要进行转换的 time_t 时间变量对应的指针,可通过 time() 或 gettimeofday() 获取得到。result : 是一个 struct tm 结构体类型指针,稍后给大家介绍 struct tm 结构体,参数 result 是可重入函数 localtime_r()需要额外提供的参数。返回值: 对于不可重入版本 localtime() 来说,成功则返回一个有效的 struct tm 结构体指针,而对于可重入版本 localtime_r() 来说,成功执行情况下,返回值将会等于参数 result ;失败则返回 NULL 。
//struct tm 结构体
struct tm {
int tm_sec; /* 秒(0-60) */
int tm_min; /* 分(0-59) */
int tm_hour; /* 时(0-23) */
int tm_mday; /* 日(1-31) */
int tm_mon; /* 月(0-11) */
int tm_year; /* 年(这个值表示的是自 1900 年到现在经过的年数) */
int tm_wday; /* 星期(0-6, 星期日 Sunday = 0、星期一=1…) */
int tm_yday; /* 一年里的第几天(0-365, 1 Jan = 0) */
int tm_isdst; /* 夏令时 */
};
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
struct tm t;
time_t sec;
/* 获取时间 */
sec = time(NULL);
if (-1 == sec) {
perror("time error");
exit(-1);
}
/* 转换得到本地时间 */
localtime_r(&sec, &t);
/* 打印输出 */
printf("当前时间: %d 年%d 月%d 日 %d:%d:%d\n",
t.tm_year + 1900, t.tm_mon, t.tm_mday,
t.tm_hour, t.tm_min, t.tm_sec);
exit(0);
}
gmtime 函数(变成struct tm 结构体所表示的时间)
gmtime()函数也可以把 time_t 时间变成一个 struct tm 结构体所表示的时间,与 localtime()所不同的是, gmtime()函数所得到的是 UTC 国际标准时间,并不是计算机的本地时间,这是它们之间的唯一区别(咱们往往是北京时间,所以比东八区国际标准时间早8个小时)
#include <time.h>struct tm *gmtime(const time_t *timep);struct tm *gmtime_r(const time_t *timep, struct tm *result);
mktime 函数(将struct tm 结构体表示的分解时间转换为 time_t 时间(日历时间),就是原来那个时间段)
#include <time.h>time_t mktime(struct tm *tm);tm : 需要进行转换的 struct tm 结构体变量对应的指针。返回值: 成功返回转换得到 time_t 时间值;失败返回 -1 。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
struct tm local_t;
time_t sec;
/* 获取时间 */
sec = time(NULL);
if (-1 == sec) {
perror("time error");
exit(-1);
}
printf("获取得到的秒数: %ld\n", sec);
localtime_r(&sec, &local_t);
printf("转换得到的秒数: %ld\n", mktime(&local_t));
exit(0);
}
//1613996624
#include <time.h>size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);s : 指向一个缓存区的指针,该缓冲区用于存放生成的字符串。max : 字符串的最大字节数。format : 这是一个用字符串表示的字段,包含了普通字符和特殊格式说明符,可以是这两种字符的任意组合。特殊格式说明符将会被替换为 struct tm 结构体对象所指时间的相应值,这些特殊格式说明符如下:

eg:譬如我要想输出"2021-01-14 16:30:25<PM> January Thursday"这样一种形式表示的时间日期
"%Y-%m-%d %H:%M:%S<%p> %B %A"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
struct tm local_t;
char tm_str[100] = {0};
time_t sec;
/* 获取时间 */
sec = time(NULL);
if (-1 == sec) {
perror("time error");
exit(-1);
}
localtime_r(&sec, &local_t);
strftime(tm_str, sizeof(tm_str), "%Y-%m-%d %A %H:%M:%S", &local_t);
printf("本地时间: %s\n", tm_str);
exit(0);
}
设置时间settimeofday
#include <sys/time.h>int settimeofday(const struct timeval *tv, const struct timezone *tz);tv : 参数 tv 是一个 struct timeval 结构体指针变量, struct timeval 结构体在前面章节内容中已经给大家介绍了,需要设置的时间便通过参数 tv 指向的 struct timeval 结构体变量传递进去。tz : 参数 tz 是个历史产物,早期实现用其来设置系统的时区信息,目前已遭废弃,在调用 settimeofday()函数时应将参数 tz 设置为 NULL 。返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno 。

进程时间
#include <sys/times.h>clock_t times(struct tms *buf);buf : times() 会将当前进程时间信息存在一个 struct tms 结构体数据中,所以我们需要提供 struct tms 变量,使用参数 buf 指向该变量
#include <stdio.h>
#include <stdlib.h>
#include <sys/times.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
struct tms t_buf_start;
struct tms t_buf_end;
clock_t t_start;
clock_t t_end;
long tck;
int i, j;
/* 获取系统的节拍率 */
tck = sysconf(_SC_CLK_TCK);
/* 开始时间 */
t_start = times(&t_buf_start);
if (-1 == t_start) {
perror("times error");
exit(-1);
}
/* *****需要进行测试的代码段***** */
for (i = 0; i < 20000; i++);
sleep(1); //休眠挂起
/* *************end************** */
/* 结束时间 */
t_end = times(&t_buf_end);
if (-1 == t_end) {
perror("times error");
exit(-1);
}
/* 打印时间 */
printf("时间总和: %f 秒\n", (t_end - t_start) / (double)tck);
printf("用户 CPU 时间: %f 秒\n", (t_buf_end.tms_utime - t_buf_start.tms_utime) / (double)tck);
printf("系统 CPU 时间: %f 秒\n", (t_buf_end.tms_stime - t_buf_start.tms_stime) / (double)tck);
exit(0);
}
clock 函数
#include <time.h>clock_t clock(void);使用该函数需要包含头文件 <time.h>返回值是到目前为止程序的进程时间,为 clock_t 类型,注意 clock() 的返回值并不是系统节拍数,如果想要获得秒数,请除以 CLOCKS_PER_SEC
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
clock_t t_start;
clock_t t_end;
int i, j;
/* 开始时间 */
t_start = clock();
if (-1 == t_start)
exit(-1);
/* *****需要进行测试的代码段***** */
for (i = 0; i < 20000; i++)
for (j = 0; j < 20000; j++)
;
/* *************end************** */
/* 结束时间 */
t_end = clock();
if (-1 == t_end)
exit(-1);
/* 打印时间 */
printf("总的 CPU 时间: %f\n", (t_end - t_start) / (double)CLOCKS_PER_SEC);
exit(0);
}
产生随机数
#include <stdlib.h>int rand(void);使用该函数需要包含头文件 <stdlib.h>
#include <stdlib.h>void srand(unsigned int seed);seed : 指定一个随机数中, int 类型的数据,一般将当前时间作为随机数种子赋值给参数 seed ,譬如 time(NULL) ,因为每次启动应用程序时间上是一样的,所以就能够使得程序中设置的随机数种子在每次启动程序时是不一样的。返回值: void常用的用法 srand(time(NULL));
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
int random_number_arr[8];
int count;
/* 设置随机数种子 */
srand(time(NULL));
/* 生成伪随机数 */
for (count = 0; count < 8; count++)
random_number_arr[count] = rand() % 100;
/* 打印随机数数组 */
printf("[");
for (count = 0; count < 8; count++) {
printf("%d", random_number_arr[count]);
if (count != 8 - 1)
printf(", ");
}
printf("]\n");
exit(0);
}
休眠(重要)
#include <unistd.h>unsigned int sleep(unsigned int seconds);seconds : 休眠时长,以秒为单位。返回值: 如果休眠时长为参数 seconds 所指定的秒数,则返回 0 ;若被信号中断则返回剩余的秒数。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
puts("Sleep Start!");
/* 让程序休眠 3 秒钟 */
sleep(3);
puts("Sleep End!");
exit(0);
}
微秒级休眠: usleep
#include <unistd.h>int usleep(useconds_t usec);usec : 休眠时长,以微秒为单位。返回值: 成功返回 0 ;失败返回 -1 ,并设置 errno 。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
puts("Sleep Start!");
/* 让程序休眠 3 秒钟(3*1000*1000 微秒) */
usleep(3 * 1000 * 1000);
puts("Sleep End!");
exit(0);
}
#include <time.h>int nanosleep(const struct timespec *req, struct timespec *rem);使用该函数需要包含头文件 <time.h> 。req : 一个 struct timespec 结构体指针,指向一个 struct timespec 变量,用于设置休眠时间长度,可精确到纳秒级别。rem : 也是一个 struct timespec 结构体指针,指向一个 struct timespec 变量,也可设置 NULL 。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
struct timespec request_t;
puts("Sleep Start!");
/* 让程序休眠 3 秒钟 */
request_t.tv_sec = 3;
request_t.tv_nsec = 0;
nanosleep(&request_t, NULL);
puts("Sleep End!");
exit(0);
}
申请堆内存(重要)
#include <stdlib.h>void *malloc(size_t size);使用该函数需要包含头文件 <stdlib.h> 。size : 需要分配的内存大小,以字节为单位。返回值: 返回值为 void * 类型,如果申请分配内存成功,将返回一个指向该段内存的指针#include <stdlib.h>void free(void *ptr);使用该函数同样需要包含头文件 <stdlib.h> 。ptr : 指向需要被释放的堆内存对应的指针。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MALLOC_MEM_SIZE (1 * 1024 * 1024)
int main(int argc, char *argv[])
{
char *base = NULL;
/* 申请堆内存 */
base = (char *)malloc(MALLOC_MEM_SIZE);
if (NULL == base) {
printf("malloc error\n");
exit(-1);
}
/* 初始化申请到的堆内存 */
memset(base, 0x0, MALLOC_MEM_SIZE);
/* 使用内存 */
/* ...... */
/* 释放内存 */
free(base);
exit(0);
}