Linux定时器的简单使用
一、基本概念
-
定时器概念
内核定时器是内核用来控制在未来某个时间点(基于jiffies)调度执行某一个函数的机制。
-
源码位置
kernel/kernel/timer.c kernel/include/linux/timer.h
-
主要概念说明
(1)结构体struct timer_list
//与4.14内核相比,该结构发生了变化,去除了data结构变量; struct timer_list { /* * All fields that change during normal runtime grouped to the * same cacheline */ struct hlist_node entry;//用来链接多个定时器组成双向链表 unsigned long expires;//需要设置的定时时间 void (*function)(struct timer_list *);//定时器回调函数 u32 flags; #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif };
(2) 相关函数说明
定时器API 简要说明 timer_setup(timer, callback, flags) 初始化定时器函数,参数分别为定时器实例对象、回调函数、flag add_timer(struct timer_list *timer) 添加定时器 mod_timer(struct timer_list *timer, unsigned long expires) 修改定时器,用于修改定时器的到期时间,在新的被传入的 expires 到来后才会执行定时器函数 del_timer(struct timer_list * timer) 删除定时器
二、以一个简单的例子来说明
struct timer_list mytimer;
int i = 0;
//定时器超时处理函数
static void mytimer_handle(struct timer_list *t)
{
printk("The timer has happened %d times!\n", i);
//这里需要说明的是,定时器在超时后会自动在系统中删除,也就是说如果定义了一个1s后执行的定时器
//1s后定时器到期后将会在系统中删除,无法完成周期性的定时任务;
//如果想要周期性执行,需要在超时处理函数中再次修改下定时器到期时间;
// mod_timer(&mytimer, jiffies + HZ);
i++;
}
static int __init timer_init(void)
{
printk("mytimer init!!\n");
timer_setup(&mytimer, mytimer_handle, 0);//(1)初始化定时器mytimer,并设置超时处理函数
mytimer.expires = jiffies + HZ;//(2)设置超时时间,1s
add_timer(&mytimer);//(3)将定时器mytimer添加到系统中
return 0;
}
static void timer_exit(void)
{
printk("mytimer exit!!\n");
del_timer(&mytimer);//(4)退出时删除定时器
}
三、案例输出说明
在超时处理函数中增加mod_timer函数修改定时器到期时间的输出如下:(每一秒都会执行定时器超时处理函数)
在超时处理函数中不增加mod_timer函数修改定时器到期时间的输出如下:(只处理一次)