工作队列实现机制(一)

转载 2012年03月25日 22:37:09

walle project android 2.2  and linux 2.6.32

一、工作项、工作队列和工作者线程

推后执行的任务叫做工作(work),描述它的数据结构为work_struct,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workqueue_struct,而工作线程就是负责执行工作队列中的工作。系统默认的工作者线程为events

工作队列(work queue)是另外一种将工作推后执行的形式。工作队列可以把工作推后,交由一个内核线程去执行—这个下半部分总是会在进程上下文执行,但由于是内核线程,其不能访问用户空间。最重要特点的就是工作队列允许重新调度甚至是睡眠。


通常,在工作队列和软中断/tasklet中作出选择非常容易。可使用以下规则:
       如果推后执行的任务需要睡眠,那么只能选择工作队列;
       如果推后执行的任务需要延时指定的时间再触发,那么使用工作队列,因为其可以利用timer延时;
       如果推后执行的任务需要在一个tick之内处理,则使用软中断或tasklet,因为其可以抢占普通进程和内核线程;
       如果推后执行的任务对延迟的时间没有任何要求,则使用工作队列,此时通常为无关紧要的任务。

实际上,工作队列的本质就是将工作交给内核线程处理,因此其可以用内核线程替换。但是内核线程的创建和销毁对编程者的要求较高,而工作队列实现了内核线程的封装,不易出错,所以我们也推荐使用工作队列。

二、工作队列使用

相关文件:

kernel/include/linux/workqueue.h

Kernel/kernel/workqueue.c

要使用工作队列,需要先创建工作项,有两种方式:

静态创建:

DECLARE_WORK(name, function); 定义正常执行的工作项

DECLARE_DELAYED_WORK(name, function); 定义延后执行的工作项

eg:

@ kernel/driver/input/keyboard/mt6516_kpd.c

@ mtk/src/custom/common/kernel/touchpanel/st1332/driver.c

static void kpd_switch_backlight(struct work_struct *work);

static DECLARE_WORK(kpd_backlight_work, kpd_switch_backlight);

static void st1332_kpd_switch_backlight(struct delayed_work *work);

static DECLARE_DELAYED_WORK(kpd_backlight_work, st1332_kpd_switch_backlight);

动态创建,运行时创建:

eg:

@ kernel/driver/input/touchscreen/tspad.c

static struct work_struct work;

struct delayed_work led_work;

static void new_ts_work(struct work_struct *work);

static void s0340_ledtime_scanf(unsigned long data);

通常在probe()函数中执行下面的操作来初始化工作项:

INIT_WORK(&work, new_ts_work);

INIT_DELAYED_WORK(&led_work, s0340_ledtime_scanf);

工作队列待执行的函数原型是:

typedef void (*work_func_t)(struct work_struct *work);

这个函数会由一个工作者线程执行,因此,函数会运行在进程上下文中。默认情况下,允许响应中断,并且不持有任何锁。如果需要,函数可以睡眠。需要注意的是,尽管该函数运行在进程上下文中,但它不能访问用户空间,因为内核线程在用户空间没有相关的内存映射。通常在系统调用发生时,内核会代表用户空间的进程运行,此时它才能访问用户空间,也只有在此时它才会映射用户空间的内存。

创建了工作项之后,在适当的时候可以通过下面的两种方式来提交工作项给工作者线程,通常我们使用的工作队列和工作者线程都是系统初始化时候默认创建的。

schedule_work(&work)

&work马上就会被调度,一旦其所在的处理器上的工作者线程被唤醒,它就会被执行

schedule_delayed_work(&delay_work, delay);

&delay_work指向的delay_work 直到delay 指定的时钟节拍用完以后才会执行。

eg :

schedule_delayed_work(&kpd_backlight_work, msecs_to_jiffies(300));

Linux工作队列实现机制

本文转载自:http://blog.csdn.net/tommy_wxie/article/details/7204306 工作项、工作队列和工作者线程  把推后执行的任务叫做工作(work),描...

工作队列实现机制(二)

三、默认工作队列和工作者线程创建过程 系统默认的工作队列名称是:keventd_wq, 默认的工作者线程叫:events/n, 这里的n是处理器的编号, 每个处理器对应一个线程。比如,单处理器的系统...
  • jkren08
  • jkren08
  • 2012年03月25日 22:37
  • 442

Linux工作队列实现机制

工作项、工作队列和工作者线程 把推后执行的任务叫做工作(work),描述它的数据结构为work_struct ,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workque...
  • sidely
  • sidely
  • 2014年09月29日 10:23
  • 878

工作队列实现机制(二)

 三、默认工作队列和工作者线程创建过程系统默认的工作队列名称是:keventd_wq, 默认的工作者线程叫:events/n, 这里的n是处理器的编号, 每个处理器对应一个线程。比如,单处理器的系统只...

Linux工作队列实现机制

把推后执行的任务叫做工作(work),描述它的数据结构为work_struct ,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workqueue_struct ,而工作线程就是...

Linux工作队列实现机制

工作项、工作队列和工作者线程 把推后执行的任务叫做工作(work),描述它的数据结构为work_struct ,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workque...

Linux2.6中断下半部分的三种实现机制---软中断/tasklet/工作队列

软中断、tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来。下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任...
  • gchww
  • gchww
  • 2012年03月21日 15:01
  • 445

rabbitmq 工作队列 java 实现

  • 2016年08月23日 17:33
  • 11KB
  • 下载

轻松搞定RabbitMQ(二)——工作队列之消息分发机制

上一篇博文中简单介绍了一下RabbitMQ的基础知识,并写了一个经典语言入门程序——HelloWorld。本篇博文中我们将会创建一个工作队列用来在工作者(consumer)间分发耗时任务。同样是翻译的...

linux工作队列机制详解

Linux自从2.6.20之后,工作队列发生了一些变化,目前从网络上搜索的资料一般都是介绍老版本的工作队列,很少见到对新版本的介绍。本文对新老版本都做了简要概述,并分别提供了简单的实作案例。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:工作队列实现机制(一)
举报原因:
原因补充:

(最多只允许输入30个字)