工作队列实现机制(一)

转载 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));

工作队列实现机制(一)

walle project android 2.2  and linux 2.6.32一、工作项、工作队列和工作者线程把推后执行的任务叫做工作(work),描述它的数据结构为work_struct ,...
  • lizhiguo0532
  • lizhiguo0532
  • 2011年06月09日 10:52
  • 5507

工作队列实现机制(二)

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

Linux 驱动之中断下半部之工作队列

1、工作队列的使用 按惯例,在介绍工作队列如何实现之前,先说说如何使用工作队列实现下半部。 步骤一、定义并初始化工作队列: 创建工作队列函数: struct workqueue_struct *...
  • xy010902100449
  • xy010902100449
  • 2015年06月03日 15:45
  • 1771

中断下半部-工作队列(比较tasklet和工作队列,推荐)

本文包含那些内容? 工作队列和tasklet的区别;中断上下文;工作队列的使用; 本文适合那些人阅读? 想了解linuxer;学习驱动开发的beginner;学习内核模块编程beginner;其...
  • maochengtao
  • maochengtao
  • 2015年01月10日 17:32
  • 482

Linux工作队列实现机制

工作项、工作队列和工作者线程 把推后执行的任务叫做工作(work),描述它的数据结构为work_struct ,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workqueue...
  • wujiangguizhen
  • wujiangguizhen
  • 2014年07月24日 14:13
  • 818

中断下半部之工作队列

一、中断的顶半部和底半部     设备的中断会打断内核中进程的正常调度和运行,而系统对更高吞吐率的追求势必要求中断服务程序尽可能地短小精悍。但是,这个良好的愿望往往与现实并不吻合。在大多数真实的系统中...
  • silent123go
  • silent123go
  • 2016年09月24日 16:03
  • 455

Nuttx 工作队列 work queue

在Linux操作系统中,工作队列(work queue)是Linux kernel中将工作推后执行的一种机制。这种机制和BH或Tasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行,...
  • chengwenyang
  • chengwenyang
  • 2017年04月19日 14:26
  • 1092

Linux中断分层工作队列学习

Linux中断嵌套处理: 概念:当一种类型的中断发生时又产生另外一种中断     慢速中断:当处理中断函数时,中断总开关是不关闭的,允许别的中断产生。 1.不同中断设备:处理中断开始。。。。。。...
  • u010827484
  • u010827484
  • 2015年06月26日 16:33
  • 631

转载_工作队列实现机制

walle project android 2.2  and linux 2.6.32 一、工作项、工作队列和工作者线程 把推后执行的任务叫做工作(work...
  • williamwanglei
  • williamwanglei
  • 2013年04月03日 13:30
  • 615

Linux内核中的软中断、tasklet和工作队列详解

[TOC] 本文基于Linux2.6.32内核版本。引言软中断、tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来。下...
  • godleading
  • godleading
  • 2016年10月30日 14:26
  • 4980
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:工作队列实现机制(一)
举报原因:
原因补充:

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