Linux 定时器的使用 内核定时器是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,其实现位于 和 kernel/timer
被调度的函数肯定是异步执行的,它类似于一种“软件中断”,而且是处于非进程的上下文中,所以调度函数必须遵守以下规则: 1) 没有 current 指针、不允许访问用户空间
因为没有进程上下文,相关代码和被中断的进程没有任何联系
2) 不能执行休眠(或可能引起休眠的函数)和调度
3) 任何被访问的数据结构都应该针对并发访问进行保护,以防止竞争条件
内核定时器的调度函数运行过一次后就不会再被运行了(相当于自动注销),但可以通过在被调度的函数中重新调度自己来周期运行
在SMP 系统中,调度函数总是在注册它的同一CPU 上运行,以尽可能获得缓存的局域性
内核定时器的数据结构 struct timer_list { struct list_head entry; unsigned long expires; void (*function)(unsigned long); unsigned long data; struct tvec_base *base; /*
*/ }; 其中 expires 字段表示期望定时器执行的 jiffies 值,到达该 jiffies 值时,将调用 function 函数,并传递 data 作为参数
当一个定时器被注册到内核之后,entry 字段用来连接该定时器到一个内核链表中
base 字段是内核内部实现所用的
需要注意的是 expires 的值是32 位的,因为内核定时器并不适用于长的未来时间点
初始化 在使用 struct timer_list 之前,需要初始化该数据结构,确保所有的字段都被正确地设置
初始化有两种方法
方法一: DEFINE_TIMER(