嵌入式Linux,系统信息与系统资源,系统时间获取转换,进程时间,相关函数讲解。

1. 系统信息

1.1 uname()函数

系统调用 uname() 用于获取有关当前操作系统内核的名称和信息,函数原型如下:
#include <sys/utsname.h>
int uname(struct utsname *buf);
函数参数和返回值解释如下:
buf struct utsname 结构体类型指针,指向一个 struct utsname 结构体类型对象。
返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno
uname() 函数用法非常简单,先定义一个 struct utsname 结构体变量,调用 uname() 函数时传入变量的地址即可,struct utsname 结构体如下所示:
truct utsname {
 char sysname[]; /* 当前操作系统的名称 */
 char nodename[]; /* 网络上的名称(主机名) */
 char release[]; /* 操作系统内核版本 */
 char version[]; /* 操作系统发行版本 */
 char machine[]; /* 硬件架构类型 */
 #ifdef _GNU_SOURCE
 char domainname[];/* 当前域名 */
 #endif
};

1.2 sysinfo 函数

sysinfo 系统调用可用于获取一些系统统计信息,其函数原型如下:
#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);
函数参数和返回值解释如下:
info struct sysinfo 结构体类型指针,指向一个 struct sysinfo 结构体类型对象。
返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno
同样 sysinfo() 函数用法也非常简单,先定义一个 struct sysinfo 结构体变量,调用 sysinfo() 函数时传入变量的地址即可,struct sysinfo 结构体如下所示:
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 */
};

1.3 gethostname 函数

此函数可用于单独获取 Linux 系统主机名,与 struct utsname 数据结构体中的 nodename 变量一样,gethostname 函数原型如下:
#include <unistd.h>
int gethostname(char *name, size_t len);
函数参数和返回值解释如下:
name 指向用于存放主机名字符串的缓冲区。
len 缓冲区长度。
返回值: 成功返回 0, ;失败将返回 -1 ,并会设置 errno

1.4  sysconf()函数

sysconf() 函数是一个库函数,可在运行时获取系统的一些配置信息,譬如页大小( page size )、主机名的最大长度、进程可以打开的最大文件数、每个用户 ID 的最大并发进程数等。其函数原型如下:
#include <unistd.h>
long sysconf(int name);
调用 sysconf() 函数获取系统的配置信息,参数 name 指定了要获取哪个配置信息,参数 name 可取以下任何一个值(都是宏定义,可通过 man 手册查询):
_SC_ARG_MAX exec 族函数的参数的最大长度
_SC_CHILD_MAX 每个用户的最大并发进程数,也就是同一个用户可以同时运行的最大进程数。
_SC_HOST_NAME_MAX 主机名的最大长度。
_SC_LOGIN_NAME_MAX 登录名的最大长度。
_SC_CLK_TCK 每秒时钟滴答数,也就是系统节拍率。
_SC_OPEN_MAX 一个进程可以打开的最大文件数。
_SC_PAGESIZE 系统页大小( page size )。
_SC_TTY_NAME_MAX 终端设备名称的最大长度。
 ......................................

2. 时间、日期

2.1 获取时间 time/gettimeofday

系统调用 time() 用于获取当前时间,以秒为单位,返回得到的值是自 1970-01-01 00:00:00 +0000 (UTC)以来的秒数,其函数原型如下:
#include <time.h>
time_t time(time_t *tloc);
函数参数和返回值解释如下:
tloc 如果 tloc 参数不是 NULL ,则返回值也存储在 tloc 指向的内存中。
返回值: 成功则返回自 1970-01-01 00:00:00 +0000 (UTC) 以来的时间值(以秒为单位);失败则返回 -1 ,并会设置 errno

2.2 gettimeofday 函数

time() 获取到的时间只能精确到秒,如果想要获取更加精确的时间可以使用系统调用 gettimeofday 来实现,gettimeofday() 函数提供微秒级时间精度,函数原型如下:
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
函数参数和返回值解释如下:
tv 参数 tv 是一个 struct timeval 结构体指针变量。
tz 参数 tz 是个历史产物,早期实现用其来获取系统的时区信息,目前已遭废弃,在调用 gettimeofday()函数时应将参数 tz 设置为 NULL
truct timeval {
 long tv_sec; /* 秒 */
 long tv_usec; /* 微秒 */
};
返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno
获取得到的时间值存储在参数 tv 所指向的 struct timeval 结构体变量中,该结构体包含了两个成员变量 tv_sec 和 tv_usec ,分别用于表示秒和微秒,所以获取得到的时间值就是 tv_sec (秒) +tv_usec (微秒),同样获取得到的秒数与 time() 函数一样,也是自 1970-01-01 00:00:00 +0000 (UTC) 到现在这段时间所经过的秒数,也就是日历时间,所以由此可知 time() 返回得到的值和函数 gettimeofday() 所返回的 tv 参数中 tv_sec 字段的数值相同。

 2.3 时间转换函数

 2.3.1 ctime 函数

ctime() 是一个 C 库函数,可以将日历时间转换为可打印输出的字符串形式, ctime() 函数原型如下:
#include <time.h>
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
函数参数和返回值解释如下:
timep time_t 时间变量指针。
返回值: 成功将返回一个 char * 类型指针,指向转换后得到的字符串;失败将返回 NULL
所以由此可知,使用 ctime 函数非常简单,只需将 time_t 时间变量的指针传入即可,调用成功便可返回字符串指针,拿到字符串指针之后,可以使用 printf 将其打印输出。但是 ctime() 是一个不可重入函数,存在一些安全上面的隐患,ctime_r() ctime() 的可重入版本,一般推荐大家使用可重入函数 ctime_r() ,可重入函数 ctime_r() 多了一个参数 buf ,也就是缓冲区首地址,所以 ctime_r() 函数需要调用者提供用于存放字符串的缓冲区。
ctime (或 ctime_r )转换得到的时间是计算机所在地对应的本地时间(譬如在中国对应的便是北京时间), 并不是 UTC 时间。

2.3.2 localtime 函数

localtime() 函数可以把 time() gettimeofday() 得到的秒数( time_t 时间或日历时间)变成一个 struct tm 结构体所表示的时间,该时间对应的是本地时间。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
使用不可重入函数 localtime() 并不需要调用者提供 struct tm 变量,而是它会直接返回出来一个 struct tm结构体指针,然后直接通过该指针访问里边的成员变量即可!虽然很方便,但是存在一些安全隐患,所以一般不推荐使用不可重入版本。
使用可重入版本 localtime_r() 调用者需要自己定义 struct tm 结构体变量、并将该变量指针赋值给参数result,在函数内部会对该结构体变量进行赋值操作。
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; /* 夏令时 */
};

2.3.3 gmtime 函数

gmtime() 函数也可以把 time_t 时间变成一个 struct tm 结构体所表示的时间,与 localtime() 所不同的是,gmtime()函数所得到的是 UTC 国际标准时间,并不是计算机的本地时间,这是它们之间的唯一区别。 gmtime()函数原型如下:
#include <time.h>
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
关于该函数的参数和返回值,这里便不再介绍,与 localtime() 是一样的。

2.3.4 mktime 函数

mktime() 函数与 localtime() 函数相反, mktime() 可以将使用 struct tm 结构体表示的分解时间转换为 time_t时间(日历时间),同样这也是一个 C 库函数,其函数原型如下所示:
#include <time.h>
time_t mktime(struct tm *tm);
函数参数和返回值解释如下:
tm 需要进行转换的 struct tm 结构体变量对应的指针。
返回值: 成功返回转换得到 time_t 时间值;失败返回 -1

2.3.5 asctime 函数

asctime() 函数与 ctime() 函数的作用一样,也可将时间转换为可打印输出的字符串形式,与 ctime() 函数的区别在于,ctime() 是将 time_t 时间转换为固定格式字符串、而 asctime() 则是将 struct tm 表示的分解时间转换为固定格式的字符串。asctime() 函数原型如下所示:
#include <time.h>
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
函数参数和返回值解释如下:
tm 需要进行转换的 struct tm 表示的时间。
buf 可重入版本函数 asctime_r 需要额外提供的参数 buf ,指向一个缓冲区,用于存放转换得到的字符串。
返回值: 转换失败将返回 NULL ;成功将返回一个 char * 类型指针,指向转换后得到的时间字符串,对于 asctime_r 函数来说,返回值就等于参数 buf

2.3.6 strftime 函数

除了 asctime() 函数之外,这里再给大家介绍一个 C 库函数 strftime() ,此函数也可以将一个 struct tm 变量表示的分解时间转换为为格式化字符串,并且在功能上比 asctime() ctime() 更加强大,它可以根据自己的喜好自定义时间的显示格式,而 asctime() ctime() 转换得到的字符串时间格式的固定的。大家感兴趣可以去查阅更详细得说明。

2.4 设置时间 settimeofday

使用 settimeofday() 函数可以设置时间,也就是设置系统的本地时间,函数原型如下所示:
#include <sys/time.h>
int settimeofday(const struct timeval *tv, const struct timezone *tz);
函数参数和返回值解释如下:
tv 参数 tv 是一个 struct timeval 结构体指针变量 ,需要设置的时间便通过参数 tv 指向的 struct timeval 结构体变量传递进去。
tz 参数 tz 是个历史产物,早期实现用其来设置系统的时区信息,目前已遭废弃,在调用 settimeofday()函数时应将参数 tz 设置为 NULL
返回值: 成功返回 0 ;失败将返回 -1 ,并设置 errno
使用 settimeofday 设置系统时间时内核会进行权限检查,只有超级用户( root )才可以设置系统时间,普通用户将无操作权限。

3. 进程时间

进程时间指的是进程从创建后(也就是程序运行后)到目前为止这段时间内使用 CPU 资源的时间总数,出于记录的目的,内核把 CPU 时间(进程时间)分为以下两个部分:
用户 CPU 时间:进程在用户空间(用户态)下运行所花费的 CPU 时间。有时也成为虚拟时间( virtual time)。
系统 CPU 时间:进程在内核空间(内核态)下运行所花费的 CPU 时间。这是内核执行系统调用或代表进程执行的其它任务(譬如,服务页错误)所花费的时间。
一般来说,进程时间指的是用户 CPU 时间和系统 CPU 时间的总和,也就是总的 CPU 时间。

3.1 times 函数

times() 函数用于获取当前进程时间,其函数原型如下所示:
#include <sys/times.h>
clock_t times(struct tms *buf);
函数参数和返回值解释如下:
buf times() 会将当前进程时间信息存在一个 struct tms 结构体数据中,所以我们需要提供 struct tms 变量,使用参数 buf 指向该变量.
返回值: 返回值类型为 clock_t (实质是 long 类型),调用成功情况下,将返回从过去任意的一个时间点(譬如系统启动时间)所经过的时钟滴答数(其实就是系统节拍数),将( 节拍数 / 节拍率 ) 便可得到秒数,返回值可能会超过 clock_t 所能表示的范围(溢出);调用失败返回 -1 ,并设置 errno
如果我们想查看程序运行到某一个位置时的进程时间,或者计算出程序中的某一段代码执行过程所花费的进程时间,都可以使用 times()函数来实现。
struct tms 结构体内容如下所示:
struct tms {
 clock_t tms_utime; /* user time, 进程的用户 CPU 时间, tms_utime 个系统节拍数 */
 clock_t tms_stime; /* system time, 进程的系统 CPU 时间, tms_stime 个系统节拍数 */
 clock_t tms_cutime; /* user time of children, 已死掉子进程的 tms_utime + tms_cutime 时间总和 */
 clock_t tms_cstime; /* system time of children, 已死掉子进程的 tms_stime + tms_cstime 时间总和 */
};

3.2 clock 函数

库函数 clock() 提供了一个更为简单的方式用于进程时间,它的返回值描述了进程使用的总的 CPU 时间(也就是进程时间,包括用户 CPU 时间和系统 CPU 时间),其函数原型如下所示:
#include <time.h>
clock_t clock(void);
函数参数和返回值解释如下:
无参数。
返回值: 返回值是到目前为止程序的进程时间,为 clock_t 类型,注意 clock() 的返回值并不是系统节拍数,如果想要获得秒数,请除以 CLOCKS_PER_SEC (这是一个宏)。如果返回的进程时间不可用或其值无法表示,则该返回值是-1
clock() 函数虽然可以很方便的获取总的进程时间,但并不能获取到单独的用户 CPU 时间和系统 CPU 时间,在实际编程当中,根据自己的需要选择。
不断学习中,共勉!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值