工作队列意义
在Linux2.6中引入了工作队列,它允许内核函数(工作)被激活,在稍后的时间里由一种叫做工作者线程的特殊线程来执行。这样的意义在于,某些内核函数可以在线程的上下文中执行,它可以被内核调度,同时也可被阻塞与睡眠。
在中断的下半部,可以将任务提交到工作队列里,稍后由特殊的内核线程来调度其中的工作,这样下半部的任务就可以放到进程的上下文中来进行。如果中断下半部需要处理诸如访问磁盘数据块(可阻塞)这样的任务,那么唯一的方式就是在进程的上下文中运行。而这里的工作队列就提供一个很好的解决方法。
工作队列原理
工作队列由工作队里子系统来实现,工作队列子系统提供创建内核线程的接口,创建的线程(工作者线程)负责维护工作队列。可以再驱动中专门创建工作者线程来完成需要推后完成的工作,不过工作者子系统提供了一个缺省的工作者线程来处理这些工作。
因此,工作者队列就变成了这样一种接口,把要推后的工作提交到工作队列,由工作者线程来负责解决工作队列里的工作。
其中缺省的工作者线程叫做events/n,这里n是处理器号;每个处理器对应一个线程。一般情况下都采用缺省的工作者线程,内核开发者反对创建新的内核线程。
工作队列结构
工作队列实现
默认情况下,每个cpu都对应一个工作者线程,每个工作者线程多维护者一个工作队列。将需要的任务关联到work,提交work到工作队列即可唤醒工作者线程,在稍后工作者线程就会处理自己的工作队列中的任务。
工作队列使用
创建工作
DECLARE(name, void (*func), void *data); //编译时静态创建
INIT_WORK(struct work_struct *work, void (*func) (void *), void *data); //运行时根据指针动态创建
其中工作处理函数原型为 void work_handler(void *data);
调度工作
schedule_work(&work);
schedule_delayed_work(&work, delay);
这里调度处理将work提交给缺省的events工作者线程,一旦工作者线程被唤醒,工作队列中的work就会被处理。
工作队列问题
1.工作与可延时函数的区别
2.为什么要用工作队列
有些任务在下半部需要被调度,因此需要再进程上下文中执行,工作队列提供了这样一个功能允许内核函数被激活,稍后在工作者线程中被调度。