tasklet(小任务机制)
一、用途
中断管理
二、特性
1. 与内核定时器相比:
相同点:中断期间运行(在“软件中断”上下文以原子的模式执行)、在调度它的CPU上运行、接收一个ulong参数
不同点:不能在某个给定的时间定时执行
2. 可被禁止或重新调用;只有启动和禁止的次数相同时tasklet才会t被执行
3. 可注册自己
4. 可被调度于一般优先级或高优先级
5. 系统负荷不重时会立刻执行,最迟不会晚于下一个定时器滴答
6. 不同tasklet可以并发,但同一tasklet则是严格串行处理的
三、接口
struct tasklet_struct
{
struct tasklet_struct *next;
unsigned long state;
atomic_t count;
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);//禁用指定的tasklet
void tasklet_disable_nosync(struct tasklet_struct *t);//禁用指定的tasklet,但不会等待任何正在运行的tasklet退出
void tasklet_enable(struct tasklet_struct *t);//启动前一个被禁止的tasklet
void tasklet_schedule(struct tasklet_struct *t);//调度执行指定的tasklet
void tasklet_hi_schedule(struct tasklet_struct *t);//调度指定的tasklet以高优先级执行
void tasklet_kill(struct tasklet_struct *t);//确保指定的tasklet不会被再次调度运行
四、实现
有两个tasklet链表(通常优先级和高优先级),它们作为per-CPU数据结构而声明。
工作队列(Workqueue)
一、用途
与tasklet类似
二、特性
1. 运行于进程上下文,可休眠
2. 始终运行于初始化它的处理器上(默认方式)
3. 可延迟给定的时间间隔
4. 与tasklet相比,具有更长的延迟且不必原子化
三、接口
#include <linux/workqueue.h>
struct workqueue_struct;//工作队列
struct work_struct;//工作(任务)
struct workqueue_struct *create_workqueue(const char *name);//可能工作队列会有多个线程
struct workqueue_struct *create_singlethread_workqueue(const char *name);//单工作线程
/* 显示地创建工作队列 */
void destroy_workqueue(struct workqueue_struct *queue);
/* 释放工作队列 */
DECLARE_WORK(name, void (*function)(void *), void *data);
/* 填充work_struct结构,用于提交任务 */
INIT_WORK(struct work_struct *work, void (*function)(void *), void *data);
PREPARE_WORK(struct work_struct *work, void (*function)(void *), void *data);
/*
运行时构造work_struct
前者用于首次初始化(会将工作结构链接到工作队列)
后者用于修改工作结构
*/
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);
/* 将工作提交到工作队列,后者至少经过一定的jiffies(delay)后才会被执行 */
int cancel_delayed_work(struct work_struct *work);
/* 取消挂起的工作,若工作在开始执行前被取消则返回非零,若工作开始执行后才取消则返回0 */
void flush_workqueue(struct workqueue_struct *queue);
/* 取消工作返回0时则需要调用此函数 */
共享队列
一、简介
若只需偶尔向队列提交任务,则使用共享的默认工作队列
二、特性
共享,不应长期独占,不能长期休眠,需要更长的时间才能获得处理时间
三、接口
int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work, unsigned long delay);
/* 提交任务到共享队列 */
void flush_scheduled_work(void);
/* 取消共享队列的工作可使用工作队列接口的cancel_delayed_work函数,但是刷新需要上面这个函数 */