7.4. 内核定时器
#include <linux/timer.h> struct timer_list { /* ... */ unsigned long expires;//期望运行的 jiffies 值 void (*function)(unsigned long); unsigned long data;//传给function的参数 };//使用前必须初始化 void init_timer(struct timer_list *timer);
//初始化一个timer_list struct timer_list TIMER_INITIALIZER(_function, _expires, _data); //初始化一个静态的timer_list void add_timer(struct timer_list * timer); int mod_timer(struct timer_list *timer, unsigned long expires);
int del_timer(struct timer_list * timer); int del_timer_sync(struct timer_list *timer);
//同 del_timer 一样,但保证函数返回时,定时器函数不在任何 CPU 上运行
//避免在SMP 系统上竞争 int timer_pending(const struct timer_list * timer);
//返回真或假来指示是否定时器已被调试运行
|
7.5. Tasklets 机制
#include <linux/interrupt.h> struct tasklet_struct { /* ... */
void (*func)(unsigned long); unsigned long data; };
void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);
//将定义好的结构体初始化,才可用
DECLARE_TASKLET(name, func, data);
//直接申明就可用了
DECLARE_TASKLET_DISABLED(name, func, data); void tasklet_disable(struct tasklet_struct *t);
void tasklet_disable_nosync(struct tasklet_struct *t); //对正在运行的tasklet无效,当它返回时,这个 tasklt 被禁止并且不会在以后被调度,直到重新使能.
void tasklet_enable(struct tasklet_struct *t); //如果这个 tasklet 已经被调度, 它会很快运行. 一个对 tasklet_enable 的调用必须匹配每个对 tasklet_disable 的调用, 因为内核跟踪每个 tasklet 的"禁止次数".
void tasklet_schedule(struct tasklet_struct *t); //调度 tasklet 执行.一般只运行一次,但可在一个tasklet中再调用,到达多次运行的目的
void tasklet_hi_schedule(struct tasklet_struct *t); //调度 tasklet 在更高优先级执行.高于一般的tasklet优先级
void tasklet_kill(struct tasklet_struct *t);
//当一个设备正被关闭或者模块卸载时,被调用。若tasklet被调度,则从激活的链表中去掉 tasklet.若tasklet在另一个 CPU 上运行,则阻塞等待tasklet终止.
|
注意:tasklet是不可中断的,一个tasklet只在一个CPU上运行
7.6. 工作队列
linux/workqueue.h
非共享队列
步骤: 1.创建工作队列 struct workqueue_struct *create_workqueue(const char *name); struct workqueue_struct *create_singlethread_workqueue(const char *name); 2.创建工作 DECLARE_WORK(name, void (*function)(void *), void *data); //一个函数搞定定义和初始化
INIT_WORK(struct work_struct *work, void (*function)(void *), void *data); PREPARE_WORK(struct work_struct *work, void (*function)(void *), void *data); //要先定义work_struct,再调用这两个函数
//INIT_WORK做更全的初始化,若需要改变工作队列,则用PREPARE_WORK
3.提交工作给一个工作队列 int queue_work(struct workqueue_struct *queue, struct work_struct *work); int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, unsigned long delay); //返回0,添加成功,非0表明已存在此工作 int cancel_delayed_work(struct work_struct *work);
//返回非0,取消成功,返回0,取消不成功,工作仍在运行 void flush_workqueue(struct workqueue_struct *queue); //确保cancel_delayed_work调用返回0后,停止运行工作 4. void destroy_workqueue(struct workqueue_struct *queue); //用完后删掉工作队列
|
共享队列
1.创建工作
同非共享
2.提交工作给一个工作队列
int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work, unsigned long delay);
//
void flush_scheduled_work(void);
//刷新 同flush_workqueue一样
注意:工作队列可休眠
阅读(1762) | 评论(0) | 转发(0) |