1. 概述
Linux 内核定时器的实现原理和硬件定时的原理比较类似,但是现实的过程要更加简单。开发者想要启用定时器,只需要分配一个定时器对象、初始化定时器对象、注册定时器对象,即可启用定时器,在不使用定时器时将定时器对象注销。
2. jiffies 变量
jiffies
是一个从内核启动开始数值就从 0
不断增加的一个变量,它用于保存内核的节拍数。3. Linux 内核的频率
内核的节拍数一秒钟变化的次数称之为内核的频率,内核的频率在内核源码目录下的
.config
文件记录 CONFIG_HZ=100
,也就代表着 jeffies
的数值一秒钟增加 100
。4. 内核定时器相关 API
#include<linux/timer.h> truct timer_list { struct hlist_node entry; // 定时器对象链表入口 unsigned long expires; // 用于设置定时器的阈值 定时一秒:jiffies+CONFIG_HZ void (*function)(struct timer_list *); // 定时器处理函数的函数指针 u32 flags; // 新版才增加的一个变量,这个值填0即可 }; //分配定时器对象 struct timer_list mytimer; // 初始化定时器对象 // 定义定时器处理函数,将作为回调函数使用 void mytimer_func(struct timer_list *timer) { } mytimer.expires = jiffies + HZ; //设置1s定时
API 的参数在上面结构体中已经注释,故省略
4.1 初始化定时器
// 注册定时器 void timer_setup(struct timer_list *timer, void (*func)(struct timer_list *), unsigned int flags) // 回调函数传入上面定义的 mytimer_func
4.2 注册定时器
// 注册进内核并使用 void add_timer(struct timer_list *timer)
4.3 再次启用定时器
// 再次启用定时器 int mod_timer(struct timer_list *timer, unsigned long expires) // 启用正在工作的定时器返回1,启用未工作的返回0
4.4 注销寄存器
// 注销寄存器 int del_timer(struct timer_list * timer) // 注销一个正在工作的定时器返回1,注销未工作的定时器返回0
5. 实例代码
整体和言,和 js 的 setTimeout 的使用和原理都基本差不多;
在处理函数中,不要使用费时操作阻塞。