一文详谈Linux中的时间管理和定时器编程
(目录)
先说一些在计算机中需要用到时间的地方:系统日志log、OS调度(时间片、定时器)等等~~
时间的计量
计时的方式发展:日晷、沙漏 -> 机械钟 -> 石英振荡器、晶振 -> 铯原子钟 -> 氢原子钟
计算机中的计时方式:
51单片机:晶振
嵌入式系统:定时器
PC:定时器
实时时钟:独立电源(CMOS电池、手机晶振)
Linux系统中的时间管理
定时器 + 实时时钟
计算机启动之后,Linux内核会先在实时时钟中读取时间,保存到内核中的全局变量xtime(墙上时间)中;jiffies:内核中的全局变量,系统启动以来的节拍数。
C语言获取当前时间
typedef long time_t;
time_t t = time(NULL); // 获得当前时间,UTC时间,1979年1月1日0点开始,以秒为单位
stime(&t); // 设置时间
时间格式的转化
#include <stdio.h>
#include <time.h>
int main(void)
{time t t=time(NULL);printf("%ld\n",t);struct tm *p;p=localtime(&t);printf ("%d-%d-%d "p->tm year +1900,p->tm mon +1,p->tm mday);printf("%d:%d:%d\n",p->tm hour, p->tm_min, p->tm_sec);p = gmtime(&t);printf ("%d-%d-%d ",p->tm year +1900,p->tm mon +1,p->tm mday);printf("%d:%d:%d\n",p->tm hour,p->tm min,p->tm sec);return 0;
}
这里p指向的struct tm类型的变量在静态内存(库内部)。
安全替代方案
为解决线程安全和重入问题,Linux 提供了:
localtime_r
(可重入版本):-
struct tm result; localtime_r(&time_val, &result); // 结果存储到用户提供的 `result` 中
-
线程安全,因为每个线程使用独立的内存。
-
用户需自行管理存储位置(如栈或堆)。
-
将时间转化为字符串
#include <stdio.h>
#include <time.h>
int main(void)
{time t t= time(NULL);printf("%ld\n",t);char *str = NULL;str =ctime(&t);printf("%s\n",str);struct tm *p;p = gmtime(&t);printf("%d-%d-%d ".,p->tm year + 1900,p->tm mon + 1,p->tm mday);printf("%d:%d:%d\n",p->tm hour, p->tm_min, p->tm_sec);str = asctime(p);printf("%s",str);return 0;
}
用户指定格式字符串
获得高精度时间
微秒
纳秒
Linux中的定时器
alarm
alarm(3) : 3秒之后,向该进程发送SIGALRM信号。
interval timer
设置的时间到达后,会重置;alarm只有一次。