一、tasklet机制
1、原理
- 类似内核定时器 ,调度一个任务稍后执行。主要用于中断的底半部
- Tasklet是一个数据结构, 它指导内核在稍后CPU空闲的时间(但不能指定确定时间),使用一个用户定义的参数,执行一个用户定义的函数
- 由内核线程——软中断(ksoftirqd/0)调度执行。在tasklet内不能睡眠
- 运行在调度它们的同一个 CPU 上
2、tasklet使用的内核API
- include <linux/interrupt.h>
- struct tasklet_struct {
void (*func)(unsigned long);
unsigned long data;
其它字段
}; - 完全初始化tasklet
- void tasklet_init(struct tasklet_struct *t, void (*func)(ulong), ulong data);
- DECLARE_TASKLET(name, func, data);
- DECLARE_TASKLET_DISABLED(name, func, data);
- void tasklet_schedule(struct tasklet_struct *t);
- 将tasklet加入系统链表,即调度tasklet运行
- tasklet执行后会自动退出系统链表,如需再次执行,需再次加入系统链表
- void tasklet_hi_schedule(struct tasklet_struct *t);
- 以高优先级调度tasklet
- void tasklet_kill(struct tasklet_struct *t);
- 将tasklet退出系统链表
- void tasklet_disable(struct tasklet_struct *t);
- void tasklet_enable(struct tasklet_struct *t);
- tasklet在disable的状态下可以被tasklet_schedule,但该tasklet必须等到tasklet_enable后才能真正运行
- tasklet_enable的次数必须与tasklet_disable的次数相等
三、Workqueue机制
1、原理
- 类似Tasklet,提交一个work到OS的特定workqueue——events/0上,以便稍后执行。主要用于中断的底半部
- work是一个数据结构, 它指导内核在稍后的时间(但不能指定确定时间)或至少延迟一个确定的时间后,执行一个用户定义的函数(不能指定参数)
- 由内核线程——events/0调度执行
- 内核线程——events/0不处于atomic context
- 缺省运行在调度它们的同一个 CPU 上
# ps
2、Tasklet与Workqueue的区别
Tasklet | Workqueue |
处于atomic context,不能sleep | 不处于atomic context,可以sleep |
运行在调度它们的同一个 CPU 上 | 默认运行在调度它们的同一个 CPU 上 |
不能指定确定时间进行调度 | 不能指定确定时间进行调度或指定至少延迟一个确定的时间后调度 |
只能提交给ksoftirqd/0 | 可以提交给events/0,也可以提交给自定义的workqueue |
tasklet函数带参数 | work函数不带参数 |
3、Workqueue API
- DECLARE_WORK(name, void (*function)(work_struct *))
- 编译时完全初始化一个work_struct
- INIT_WORK(struct work_struct *work, void (*function)(work_struct *))
- 完全初始化一个work_struct
- int schedule_work(struct work_struct *work)
- 将work提交给默认的kevent
- •nt schedule_delayed_work(struct work_struct *work, ulong delay)
- 将work提交给默认的kevent,但延后delay后调度
- int cancel_delayed_work(struct work_struct *work);
- 取消提交的work
- void flush_scheduled_work(void)
- 将kevent中的work全部取消
- struct workqueue_struct *create_workqueue(const char *name)
- struct workqueue_struct *create_singlethread_workqueue(const char *name)
- 创建自己的workqueue,并与每个CPU(或单个CPU)绑定
- int queue_work(struct workqueue_struct *queue, struct work_struct *work)
- int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, ulong delay)
- 将work提交给queue
- void flush_workqueue(struct workqueue_struct *queue)
- 将queue中的work全部取消
- void destroy_workqueue(struct workqueue_struct *queue)
- 删除自己创建的queue