博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
workqueue
阅读量:2455 次
发布时间:2019-05-10

本文共 2080 字,大约阅读时间需要 6 分钟。

什么是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_workqueue对workqueue队列进行初始化时,内核就开始为用户分配一个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都创建一个内核线程。输入参数:

@name:workqueue的名称

2

create_singlethread_workqueue

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

@name:workqueue名称

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。

转载地址:http://xhnhb.baihongyu.com/

你可能感兴趣的文章
Linux中的/ dev / null
查看>>
c语言双精度的格式说明符_C中的格式说明符
查看>>
c中的结构体嵌套问题_C中的结构
查看>>
struts2 拦截器_Struts 2拦截器示例
查看>>
mongodb mac安装_在Mac OS X上安装MongoDB
查看>>
struts2数据库操作_Struts 2操作错误和操作消息
查看>>
Java棘手面试问题
查看>>
多重继承java_Java中的多重继承
查看>>
stl标准模板库_如何在C ++ STL(标准模板库)中使用Pair
查看>>
sql联接查询_SQL联接
查看>>
计算器的二进制功能java_Java二进制文字– Java 7功能
查看>>
mac os maven_如何在Mac OS上安装Maven
查看>>
c++语句switch语句_C ++中的Switch语句
查看>>
struts2登录注册示例_Struts 2文件上传示例
查看>>
linux中安装pip_如何在Linux中安装PIP
查看>>
在Ubuntu 18.04中更改时区
查看>>
linux tee命令_Linux tee命令示例
查看>>
linux 十大发行版_2020年十大最佳Linux发行版
查看>>
tkinter教程_Tkinter教程–第2部分
查看>>
在Ubuntu 18.04上安装MongoDB
查看>>