原创 Linux中Workqueue机制分析

2008-7-10 19:39 20583 9 12 分类: MCU/ 嵌入式


    走入Linux的殿堂已经有一年有余了,在这里我想将Linux的各种实现机制分析一遍,一方面对自己来说也是温故而知新,另一方面,促进大家的交流,最好能够给大家一些抛砖引玉的启迪。我是硬件出身,搞硬件已经好多年了,从是专门软件开发也接近两年了,在这一段时间内我越发认为软硬件协同设计是未来发展的主流,软硬件的界限越来越模糊,软硬件的设计思想是相通的,实现方法是各异的,实现的结果上当然也存在较大差别,因此,很有必要做好软硬件的协同设计。本着这样的想法,我想将我所认识的Linux分析一遍,特别是一些我认为精华和重要的机制,另外在讨论过程中,我会插入一些其他的OS实现机制,进行对比分析,我把这一类blog文章划归为“Linux机制分析”,希望大家支持。



 



什么是workqueue



Linux中的Workqueue机制就是为了简化内核线程的创建。通过调用workqueue的接口就能创建内核线程。并且可以根据当前系统CPU的个数创建线程的数量,使得线程处理的事务能够并行化。



workqueue是内核中实现简单而有效的机制,他显然简化了内核daemon的创建,方便了用户的编程,



 



Workqueue机制的实现



Workqueue机制中定义了两个重要的数据结构,分析如下:



1、         
cpu_workqueue_struct结构。该结构将CPU和内核线程进行了绑定。在创建workqueue的过程中,Linux根据当前系统CPU的个数创建cpu_workqueue_struct。在该结构主要维护了一个任务队列,以及内核线程需要睡眠的等待队列,另外还维护了一个任务上下文,即task_struct



2、         
work_struct结构是对任务的抽象。在该结构中需要维护具体的任务方法,需要处理的数据,以及任务处理的时间。该结构定义如下:



struct work_struct {



              unsigned
long pending;



               struct
list_head entry;                  /*
将任务挂载到queue的挂载点 */



               void
(*func)(void *);                   /*
任务方法 */



               void
*data;                                  /*
任务处理的数据*/



               void
*wq_data;                           /*
work
的属主 */



               strut
timer_list timer;                   /*
任务延时处理定时器 */



};



      



       当用户调用workqueue的初始化接口create_workqueue或者create_singlethread_workqueueworkqueue队列进行初始化时,内核就开始为用户分配一个workqueue对象,并且将其链到一个全局的workqueue队列中。然后Linux根据当前CPU的情况,为workqueue对象分配与CPU个数相同的cpu_workqueue_struct对象,每个cpu_workqueue_struct对象都会存在一条任务队列。紧接着,Linux为每个cpu_workqueue_struct对象分配一个内核thread,即内核daemon去处理每个队列中的任务。至此,用户调用初始化接口将workqueue初始化完毕,返回workqueue的指针。



 



       在初始化workqueue过程中,内核需要初始化内核线程,注册的内核线程工作比较简单,就是不断的扫描对应cpu_workqueue_struct中的任务队列,从中获取一个有效任务,然后执行该任务。所以如果任务队列为空,那么内核daemon就在cpu_workqueue_struct中的等待队列上睡眠,直到有人唤醒daemon去处理任务队列。



 



       Workqueue初始化完毕之后,将任务运行的上下文环境构建起来了,但是具体还没有可执行的任务,所以,需要定义具体的work_struct对象。然后将work_struct加入到任务队列中,Linux会唤醒daemon去处理任务。



 



       上述描述的workqueue内核实现原理可以描述如下:
点击看大图


    在Workqueue机制中,提供了一个系统默认的workqueue队列——keventd_wq,这个队列是Linux系统在初始化的时候就创建的。用户可以直接初始化一个work_struct对象,然后在该队列中进行调度,使用更加方便。



 



Workqueue编程接口




序号



接口函数



说明



1



create_workqueue



用于创建一个workqueue队列,为系统中的每个CPU都创建一个内核线程。输入参数:


@nameworkqueue的名称



2



create_singlethread_workqueue



用于创建workqueue,只创建一个内核线程。输入参数:


@nameworkqueue名称



3



destroy_workqueue



释放workqueue队列。输入参数:


@ workqueue_struct:需要释放的workqueue队列指针



4



schedule_work



调度执行一个具体的任务,执行的任务将会被挂入Linux系统提供的workqueue——keventd_wq输入参数:


@ work_struct:具体任务对象指针



5



schedule_delayed_work



延迟一定时间去执行一个具体的任务,功能与schedule_work类似,多了一个延迟时间,输入参数:


@work_struct:具体任务对象指针


@delay:延迟时间



6



queue_work



调度执行一个指定workqueue中的任务。输入参数:


@ workqueue_struct:指定的workqueue指针


@work_struct:具体任务对象指针



7



queue_delayed_work



延迟调度执行一个指定workqueue中的任务,功能与queue_work类似,输入参数多了一个delay




 





文章评论3条评论)

登录后参与讨论

用户377235 2012-10-2 11:08

兄弟看的是2.6 的source 把,从3.0 以后虽然API 兼容,但实现已经推倒重来了,实现了动态的负载均衡。甚至原来的create_workqueue 之类的API 都已经被alloc_workqueue代替

用户411565 2008-7-11 09:16

riple过奖了,我这才刚刚开始~~

ash_riple_768180695 2008-7-10 21:59

tiloog是我的榜样,学一门专一门。心服口服。

用户160754 2008-7-1 16:19

没有做的事情怕什么嘛

用户160754 2008-7-1 16:12

太过分了,你怕什么嘛,删除我的评论 http://group.ednchina.com/460/11488.aspx
相关推荐阅读
用户411565 2012-12-18 12:58
我的存储之道博客
大家好,最近一直在做存储方面的工作,所以我在51CTO上专门开辟了一个空间讨论存储相关的问题,喜欢存储的朋友可以可以访问我的存储博客: 存储之道 (http://alanwu.blog.51cto...
用户411565 2012-04-06 21:39
SAS Cable可以有多长?
SAS接口是高端硬盘的主流接口,是存储系统的理想选择。我们知道高速信号的传输距离和传输线相关的,那么SAS作为外部通信接口,其Cable线具体可以有多长呢? 我在网上找到上图所示的眼图测...
用户411565 2012-04-06 21:38
对TRIM SCSI命令的一些分析
前一段时间做了一些对SSD方面进行优化的工作,SSD最大的问题在于长时间使用之后,IO性能会急剧下降。其主要问题在于为了防止“写放大”问题的产生,SSD的firmware采用了类似于log方式的算...
用户411565 2012-04-06 21:35
惊叹!我们的跨洋网络
  每次地质自然灾害的时候,总会伴随着网络的问题,这是由于我们的越洋光纤网络出了故障,受到自然力的破坏而导致断裂。越洋光纤,听起来的确是件非常不可思议的事情,工程量非常的巨大,但正是如此伟大的...
用户411565 2012-04-06 21:33
科学仪器网络模型
科学仪器概述     科学仪器发展趋势 科学是从测量开始的,科学仪器是信息技术的源头,是信息产业的重要组成部分,是现代科学与工业的基石。科学仪器产业的发展关系到国家科学研究实力、生...
用户411565 2012-04-06 21:16
谈谈RAID产品与技术
说起RAID,学计算机的同学马上会说RAID技术简单啊,就是将数据条带化,然后计算一些冗余数据,一并写入磁盘。通过RAID技术一方面提高系统的IO性能;另一方面提高系统的可靠性。单纯从RAID的原...
我要评论
3
9
关闭 站长推荐上一条 /2 下一条