1. 系统信息
1.1 uname()
获取有关操作系统内核的名称和信息
#include <sys/utsname.h> int uname(struct utsname *buf) struct utsname { char sysname[]; /* 当前操作系统的名称 */ char nodename[]; /* 网络上的名称(主机名) */ char release[]; /* 操作系统内核版本 */ char version[]; /* 操作系统发行版本 */ char machine[]; /* 硬件架构类型 */ #ifdef _GNU_SOURCE char domainname[];/* 当前域名 */ #endif };
1.2 sysinfo()
获取一些系统统计信息
#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 */ };
1.3 gethostname()
获取linux系统主机名
#include <unistd.h> int gethostname(char *name, size_t len);
1.4 sysconf()
获取系统的一些配置信息,如页大小,主机名最大长度,进程可打开的最大文件数等等
#include <unistd.h> long sysconf(int name);
- _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. 系统时间
操作系统中一般会有两个时钟,一个系统时钟(system clock),一个实时时钟(Real time clock),也叫 RTC;系统时钟由系统启动之后由内核来维护,譬如使用 date 命令查看到的就是系统时钟,所以在系统
关机情况下是不存在的;而实时时钟一般由 RTC 时钟芯片提供,RTC 芯片有相应的电池为其供电,以保证系统在关机情况下 RTC 能够继续工作、继续计时
2.1 time()
获取当前时间,返回的是自1970-01-01 00:00:00 +0000(UTC) 以来的秒数,即时间戳
#include <time.h> // 如果参数tloc不是NULL, 则返回值也会存在该指针指向的内存内 time_t time(time_t *tloc); // time_t 实际上就是long int
2.2 gettimeofday()
获取更加精确的当前时间,精确到微秒级别
#include <sys/time.h> // 参数tz已经废弃,传NULL即可 int gettimeofday(struct timeval *tv, struct timezone *tz); struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ };
2.4 ctime()
将前面获取的时间转为字符串格式的时间
#include <time.h> char *ctime(const time_t *timep); char *ctime_r(const time_t *timep, char *buf); // 可重入版本,推荐使用该函数
2.5 localtime()
将time()获取的日历时间转换为一个struct tm结构体的时间
#include <time.h> struct tm *localtime(const time_t *timep); struct tm *localtime_r(const time_t *timep, struct tm *result); // 推荐使用 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.6 gmtime()
与localtime()功能一样,唯一不同的是gmtime()得到的是UTC国际标准时间
#include <time.h> struct tm *gmtime(const time_t *timep); struct tm *gmtime_r(const time_t *timep, struct tm *result);
2.7 mktime()
与localtime函数相反,该函数将struct tm结构体的时间转为time_t时间
#include <time.h> time_t mktime(struct tm *tm);
2.8 asctime()
与ctime()的区别是,ctime转换的是time_t时间,二该函数转换的是struct tm结构体的函数
#include <time.h> char *asctime(const struct tm *tm); char *asctime_r(const struct tm *tm, char *buf);
2.9 strftime()
将struct tm时间格式化成自定义格式的字符串时间
#include <time.h> size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
返回值:如果转换得到的目标字符串不超过最大字节数(也就是 max),则返回放置到 s 数组中的字节
数;如果超过了最大字节数,则返回 0。
说明符 | 表示含义 | 实例 |
%a | 星期的缩写 | Sun |
%A | 星期的完整名称 | Sunday |
%b | 月份的缩写 | Mar |
%B | 月份的完整名称 | March |
%c | 系统当前语言环境对应的首选日期和时间表示形式 | |
%C | 世纪(年/100) | 20 |
%d | 十进制数表示一个月中的第几天(01-31) | 15、05 |
%D | 相当于%m/%d/%y | 01/14/21 |
%e | 与%d 相同,但是单个数字时,前导 0 会被去掉 | 15、5 |
%F | 相当于%Y-%m-%d | 2021-01-14 |
%h | 相当于%b | Jan |
%H | 十进制数表示的 24 小时制的小时(范围 00-23) | 01、22 |
%I | 十进制数表示的 12 小时制的小时(范围 01-12) | 01、11 |
%j | 十进制数表示的一年中的某天(范围 001-366) | 050、285 |
%k | 与%H 相同,但是单个数字时,前导 0 会被去掉(范围 0-23) | 1、22 |
%l | 与%I 相同,但是单个数字时,前导 0 会被去掉(范围 1-12) | 1、11 |
%m | 十进制数表示的月份(范围 01-12) | 01、10 |
%M | 十进制数表示的分钟(范围 00-59) | 01、55 |
%n | 换行符 |
%p | 根据给定的时间值,添加“AM”或“PM” | PM |
%P | 与%p 相同,但会使用小写字母表示 | pm |
%r | 相当于%I:%M:%S %p 12:15:31 | PM |
%R | 相当于%H:%M | 12:16 |
%S | 十进制数表示的秒数(范围 00-60) | 05、30 |
%T | 相当于%H:%M:%S | 12:20:03 |
%u | 十进制数表示的星期(范围 1-7,星期一为 1) | 1、5 |
%U | 十进制数表示,当前年份的第几个星期(范围 00-53),从第一个星期日作为 01 周的第一天开始 | |
%W | 十进制数表示,当前年份的第几个星期(范围 00-53),从第一个星期一作为第 01 周的第一天开始 | |
%w | 十进制数表示的星期,范围为 0-6,星期日为 0 |
%x | 系统当前语言环境的首选日期表示形式,没有时间 | 01/14/21 |
%X | 系统当前语言环境的首选时间表示形式,没有日期 | 12:30:16 |
%y | 十进制数表示的年份(后两字数字) | 21 |
%Y | 十进制数表示的年份(4 个数字) | 2021 |
%% | 输出%符号 | % |
2.10 settimeofday()
设置系统的本地时间(只有超级用户才具有该权限)
#include <sys/time.h> // 参数tz已废弃,传入NULL即可 int settimeofday(const struct timeval *tv, const struct timezone *tz);
2.11 各个接口的关系图
2.12 times()
获取当前进程时间
#include <sys/times.h> clock_t times(struct tms *buf); // 注意:buf参数的数据仅仅是CPU时间,是不包括休眠所占用的时间的,所以在进程中使用的sleep()函数不会计入 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 时间总和 */ };
返回值:返回值类型为 clock_t(实质是 long 类型),调用成功将返回时钟滴答数(系统节拍数),将(节拍数 / 节拍率)便可得到秒数。返回值可能会超过 clock_t 所能表示的范围(溢出);调用失败返回-1,并设置 errno。
节拍率通过函数sysconf(_SC_CLOCK_PER_SEC)获得)
2.13 clock()
返回进程使用的总CPU时间
注意: 返回值并不是系统节拍数,如果想要获得秒数,请除以 CLOCKS_PER_SEC(这是一个宏)
#include <time.h> clock_t clock(void);
3. 随机数
3.1 rand()
产生一个0~RAND_MAX的随机数
#include <stdlib.h> int rand(void);
3.2 srand()
为随机函数rand()设置种子,通常设置的是时间time(NULL)。如果不使用该函数设置种子,那么系统会自动设置为1,这样的话每次运行程序时,rand()出来的随机值是一样的。(因为随机数是不可能实现的,所以在编程上都是使用的某种算法生成的,如果种子一样的话,所生成的随机数也是一样的)
#include <stdlib.h> void srand(unsigned int seed);
4. 休眠(延时)
休眠状态下,该进程会失去 CPU使用权,退出系统调度队列,直到休眠结束
4.1 sleep()
实现秒级休眠
#include <unistd.h> unsigned int sleep(unsigned int seconds); // 因为参数是int型,所以是不可以传入小数点,如0.1。而python可以
4.2 usleep()
实现微秒级休眠
#include <unistd.h> int usleep(useconds_t usec);
4.3 nanosleep()
纳秒级延时
#include <time.h> int nanosleep(const struct timespec *req, struct timespec *rem); struct timespec { time_t tv_sec; /* 秒*/ long tv_nsec; /* 纳秒 */ };
返回值:在成功休眠达到请求的时间间隔后,nanosleep()返回 0;如果中途被信号中断或遇到错误,则返回-1,并将剩余时间记录在参数 rem 指向的 struct timespec 结构体变量中(参数 rem 不为 NULL 的情况下,如果为 NULL 表示不接收剩余时间),还会设置 errno 标识错误类型。
5. 申请堆内存
5.1 malloc()
在堆上分配一段内存
#include <stdlib.h> void *malloc(size_t size);
返回值: 成功就返回地址的首地址; 失败就返回NULL
5.2 free()
释放申请到的堆内存
当进程终止时,内核会将其占用的所有内存都返还给操作系统,这包括在堆内存中由 malloc()函数所分配的内存空间, 但我们还是尽量自己释放,以免造成内存泄漏
#include <stdlib.h> void free(void *ptr);
5.3 calloc()
在堆上申请nemmb*size大小的空间, 并自动将该内存初始化为0
#include <stdlib.h> void *calloc(size_t nmemb, size_t size);
5.4 posix_memalign()
分配对齐内存, 分配的内存地址将是alignment的整数倍。
alignment参数要求: 必须是2的幂次方,同时也要是sizeof(void *)的整数倍。
#include<stdlib.h> int posix_memalign(void **memptr, size_t alignment, size_t size);
5.5 aligned_alloc()
分配size个字节大小的内存空间
alignment要求: 必须是2的幂次方
#include<stdlib.h> void *aligned_alloc(size_t alignment, size_t size);