一、系统信息
系统标识uname
获取当前操作系统内核的名称和信息。
cpp
#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
};
sysinfo函数
获取系统统计信息。
cpp
#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);
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 */
};
gethostname函数
单独获取Linux系统主机名。
cpp
#include <unistd.h>
int gethostname(char *name, size_t len);
name:指向用于存放主机名字符串的缓冲区。
len:缓冲区长度。
返回值:成功返回 0,;失败将返回-1,并会设置 errno。
sysconf函数
获取系统的配置信息。
cpp
#include <unistd.h>
long sysconf(int name);
二、时间、日期
系统的本地时间由时区配置文件/etc/localtime 定义,通常链接到/usr/share/zoneinfo 目录下的某一个文件。
修改 Ubuntu 系统本地时间的时区信息:
cpp
sudo rm -rf localtime #删除原有链接文件
sudo ln -s /usr/share/zoneinfo/EST localtime #重新建立链接文件
获取时间time/gettimeofday
cpp
#include <time.h>
time_t time(time_t *tloc);
tloc:如果 tloc 参数不是 NULL,则返回值也存储在 tloc 指向的内存中。
返回值:成功则返回自 1970-01-01 00:00:00 +0000 (UTC)以来的时间值(以秒为单位);失败则返回-1,
并会设置 errno。
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
tv:参数 tv 是一个 struct timeval 结构体指针变量,struct timeval 结构体在前面章节内容中已经给大家介
绍过,具体参考示例代码 5.6.3。
tz:参数 tz 是个历史产物,早期实现用其来获取系统的时区信息,目前已遭废弃,在调用 gettimeofday()
函数时应将参数 tz 设置为 NULL。
返回值:成功返回 0;失败将返回-1,并设置 errno。
时间转换函数

cpp
1.ctime
将日历时间转换为可打印输出的字符串形式:
#include <time.h>
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
timep:time_t 时间变量指针。
返回值:成功将返回一个 char *类型指针,指向转换后得到的字符串;失败将返回 NULL。
2.localtime
把 time()或 gettimeofday()得到的秒数(time_t 时间或日历时间)变成一个 struct tm
结构体所表示的时间,该时间对应的是本地时间。
#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 {
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; /* 夏令时 */
};
3.gmtime
把 time_t 时间变成一个 struct tm 结构体所表示的时间,与 localtime()所不同的是,gmtime()函数所得到的是 UTC 国际标准时间,不是计算机的本地时间。
#include <time.h>
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
4.mktime
将使用 struct tm 结构体表示的分解时间转换为 time_t时间(日历时间)。
#include <time.h>
time_t mktime(struct tm *tm);
tm:需要进行转换的 struct tm 结构体变量对应的指针。
返回值:成功返回转换得到 time_t 时间值;失败返回-1。
5.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。
6.strftime
将一个 struct tm 变量表示的分解时间转换为为格式化字符串,并自定义时间的显示格式。
#include <time.h>
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
s:指向一个缓存区的指针,该缓冲区用于存放生成的字符串。
max:字符串的最大字节数。
format:这是一个用字符串表示的字段,包含了普通字符和特殊格式说明符,可以是这两种字符的任意
组合。
tm:指向 struct tm 结构体对象的指针。
返回值:如果转换得到的目标字符串不超过最大字节数(也就是 max),则返回放置到 s 数组中的字节
数;如果超过了最大字节数,则返回 0。
7.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。
三、进程时间
- 用户 CPU 时间:进程在用户空间(用户态)下运行所花费的 CPU 时间。有时也成为虚拟时间(virtual time)。
- 系统 CPU 时间:进程在内核空间(内核态)下运行所花费的 CPU 时间。这是内核执行系统调用或代表进程执行的其它任务(譬如,服务页错误)所花费的时间。
一般来说,进程时间指的是用户 CPU 时间和系统 CPU 时间的总和,也就是总的 CPU 时间。
1.times
获取当前进程时间。
cpp
#include <sys/times.h>
clock_t times(struct tms *buf);
buf:times()会将当前进程时间信息存在一个 struct tms 结构体数据。
返回值:返回值类型为 clock_t(实质是 long 类型),调用成功情况下,
将返回从过去任意的一个时间
点(譬如系统启动时间)所经过的时钟滴答数(其实就是系统节拍数),
将(节拍数 / 节拍率)便可得到秒数,
返回值可能会超过 clock_t 所能表示的范围(溢出);调用失败返回-1,并设置 errno。
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 时间总和 */
};
2.clock
进程使用的总的 CPU 时间 。
cpp
#include <time.h>
clock_t clock(void);
注意 clock()的返回值并不是系统节拍数,如果想要获得秒数,
请除以 CLOCKS_PER_SEC(这是一个宏)。
如果返回的进程时间不可用或其值无法表示,则该返回值是-1。
四、产生随机数
rand
cpp
#include <stdlib.h>
int rand(void);
返回值:返回一个介于 0 到 RAND_MAX(包含)之间的值,也就是数学上的[0, RAND_MAX]。
每一次运行程序所得到的随机数序列都是相同的。
srand
cpp
#include <stdlib.h>
void srand(unsigned int seed);
seed:指定一个随机数中,int 类型的数据,一般尝尝将当前时间作为随机数种子赋值给参数 seed,
譬如 time(NULL),因为每次启动应用程序时间上是一样的,
所以就能够使得程序中设置的随机数种子在每次
启动程序时是不一样的。
srand(time(NULL));
五、休眠(延时)
秒级休眠sleep
cpp
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
seconds:休眠时长,以秒为单位。
返回值:如果休眠时长为参数 seconds 所指定的秒数,则返回 0;若被信号中断则返回剩余的秒数。
微秒级休眠usleep
cpp
#include <unistd.h>
int usleep(useconds_t usec);
usec:休眠时长,以微秒为单位。
返回值:成功返回 0;失败返回-1,并设置 errno。
纳秒级休眠nanosleep
cpp
#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);
req:一个 struct timespec 结构体指针,指向一个 struct timespec 变量,用于设置休眠时间长度,
可精确到纳秒级别。
rem:也是一个 struct timespec 结构体指针,指向一个 struct timespec 变量,也可设置 NULL。
返回值:在成功休眠达到请求的时间间隔后,nanosleep()返回 0;
如果中途被信号中断或遇到错误,则返回-1,并将剩余时间记录在
参数 rem 指向的 struct timespec 结构体变量中(参数 rem 不为 NULL 的情况下,
如果为 NULL 表示不接收剩余时间),还会设置 errno 标识错误类型。
文件描述符定时器timerfd
cpp
#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags);
clockid:时钟源(CLOCK_REALTIME 或 CLOCK_MONOTONIC)
flags:非阻塞(TFD_NONBLOCK)或自动关闭(TFD_CLOEXEC)
int timerfd_settime(int fd, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value);
new_value:定义首次超时时间(it_value)和周期间隔(it_interval)
int timerfd_gettime(int fd, struct itimerspec *curr_value);
六、申请堆内存
malloc,free
cpp
#include <stdlib.h>
void *malloc(size_t size);
size:需要分配的内存大小,以字节为单位。
返回值:返回值为 void *类型,如果申请分配内存成功,将返回一个指向该段内存的指针,
void *并不是说没有返回值或者返回空指针,
而是返回的指针类型未知,所以在调用 malloc()时通常需要进行强制类型转换,
将 void *指针类型转换成我们希望的类型;如果分配内存失败(譬如系统堆内存不足)将返回 NULL,
如果参数 size 为 0,返回值也是 NULL。
#include <stdlib.h>
void free(void *ptr);
ptr:指向需要被释放的堆内存对应的指针。
calloc
cpp
#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);
分配对齐内存
cpp
#include <stdlib.h>
int posix_memalign(void **memptr, size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void *valloc(size_t size);
#include <malloc.h>
void *memalign(size_t alignment, size_t size);
void *pvalloc(size_t size);
七、proc文件系统
proc 文件系统挂载在系统的/proc 目录下,对于内核开发者(譬如驱动开发工程师)来说,proc 文件 系统给了开发者一种调试内核的方法:通过查看/proc/xxx 文件来获取到内核特定数据结构的值,在添加了新功能前后进行对比,就可以判断此功能所产生的影响是否合理。
-
进程PID
-
cmdline:内核启动参数;
-
cpuinfo:CPU 相关信息;
-
iomem:IO 设备的内存使用情况;
-
interrupts:显示被占用的中断号和占用者相关的信息;
-
ioports:IO 端口的使用情况;
-
kcore:系统物理内存映像,不可读取;
-
loadavg:系统平均负载;
-
meminfo:物理内存和交换分区使用情况;
-
modules:加载的模块列表;
-
mounts:挂载的文件系统列表;
-
partitions:系统识别的分区表;
-
swaps:交换分区的利用情况;
-
version:内核版本信息;
-
uptime:系统运行时间;