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

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

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。

work queue 的使用实例:

 

struct my_work_t {

char *name;

struct work_struct work;  //作为自己数据结构的成员,然后用container_of获得my_work_t的指针

};
void my_func(struct work_struct *work)

{

struct my_work_t *my_work = container_of (work, struct my_work_t, work);

printk(KERN_INFO “Hello world, my name is %s!/n”, my_work->name);

}
struct workqueue_struct *my_wq = create_workqueue(“my wq”);      //创建自己的work queue

struct my_work_t my_work;

my_work.name = “Jack”;

INIT_WORK(&(my_work.work), my_func);          //初始化自己的work queue

queue_work(my_wq, &(my_work.work));

destroy_workqueue(my_wq);                     //销毁自己的work queue

Workqueue机制的实现的更多相关文章

  1. Linux kernel workqueue机制分析

    Linux kernel workqueue机制分析 在内核编程中,workqueue机制是最常用的异步处理方式.本文主要基于linux kernel 3.10.108的workqueue文档分析其基 ...

  2. Linux kernel workqueue机制分析【转】

    转自:http://www.linuxsir.org/linuxjcjs/15346.html 在内核编程中,workqueue机制是最常用的异步处理方式.本文主要基于linux kernel 3.1 ...

  3. workqueue机制分析之process_one_work分析

    工作者线程不断执行,从work_poll结构中卸下一个work, 然后进入函数process_one_work 来执行这个work. process_one_work(struct worker *w ...

  4. Linux内核中的Workqueue机制分析

    1. 什么是workqueue Linux中的workqueue(工作队列)主要是为了简化在内核创建线程而设计的.通过相应的工作队列接口,可以使开发人员只关心与特定功能相关的处理流程,而不必关心内核线 ...

  5. workqueue机制分析之wb_workfn函数

    上面一篇文章说到: process_one_work中最重要的一件事情就是worker->current_func(work); 这里就具体到一项很具体的任务了,由于我要研究文件系统嘛,所以很自 ...

  6. Linux workqueue疑问【转】

    转自:http://blog.csdn.net/angle_birds/article/details/9387365 各位大神,你们好.我在使用workqueue的过程中遇到一个问题. 项目采用uC ...

  7. Linux workqueue工作原理 【转】

    转自:http://blog.chinaunix.net/uid-21977330-id-3754719.html 转自:http://bgutech.blog.163.com/blog/static ...

  8. workqueue --最清晰的讲解【转】

    转自:https://www.cnblogs.com/zxc2man/p/6604290.html 带你入门: 1.INIT_WORK(struct work_struct *work, void ( ...

  9. Linux中断管理 (3)workqueue工作队列

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

随机推荐

  1. 用PS做PNG格式底色是透明的logo

    有时我们需要底色为透明色的logo图片,但是一般的图片底色都是白色的,覆盖在其它图片上会显示白色. 本文介绍如何用PS CS6制作透明底色的图片. 1.首先我们确定所选图片的大小(即分辨率大小),在资 ...

  2. Django 2.0 学习(15):Web框架

    Web框架的本质 对于学习Python的同学,相信对Flask.Django.Web.py等不会陌生,这些都是Python语言的web框架.那么问题来了,web服务器是什么?它和web框架有什么关系? ...

  3. BZOJ3717 PA2014Pakowanie(状压dp)

    显然贪心地有尽量先往容量大的背包里放.设f[i]为i子集物品最小占用背包数,g[i]为该情况下最后一个背包的剩余容量,转移显然. #include<iostream> #include&l ...

  4. IP组播技术

      1  概述 1.1  产生背景 传统的IP通信有两种方式:一种是在源主机与目的主机之间点对点的通信,即单播:另一种是在源主机与同一网段中所有其它主机之间点对多点的通信,即广播.如果要将信息发送给多 ...

  5. mysql索引长度的一些限制

    一.myisam存储引擎 1. 数据库版本:阿里云RDS MySQL5.1 mysql> select @@version;+-------------------------------+| ...

  6. atcoder 2017Code festival C ——D题 Yet Another Palindrome Partitioning(思维+dp)

    题目大意: 把一个字符串s分割成m个串,这m个串满足至多有一种字符出现次数为奇数次,其他均为偶数次,问m的最小值 题解: 首先我们想一下纯暴力怎么做 显然是可以n^2暴力的,然后dp[i]表示分割到i ...

  7. mysql安装使用详细教程

    1.数据库存储数据的方式与Excel类似. 一.数据库介绍 1.什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访 ...

  8. ZJOI2018 D1

    归途的车上满是悲伤的气息 虽然早就预言到D1会滚粗,但一切都结束之后还是特别难过. 延时15min 50min T1 30pts 1.5h T2 10pts 2.5h T1 50pts 4.5h T3 ...

  9. 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告

    P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...

  10. kerberos中的spn详解

    0x01 SPN定义    服务主体名称(SPN)是Kerberos客户端用于唯一标识给特定Kerberos目标计算机的服务实例名称.Kerberos身份验证使用SPN将服务实例与服务登录帐户相关联. ...