中断下半部-工作队列

工作队列和tasklet的区别;中断上下文;工作队列的使用;

为什么还需要工作队列?

工作队列(work queue)是另外一种将中断的部分工作推后的一种方式,它可以实现一些tasklet不能实现的工作,比如工作队列机制可以睡眠。这种差异的本质原因是,在工作队列机制中,将推后的工作交给一个称之为工作者线程(worker thread)的内核线程去完成(单核下一般会交给默认的线程events/0)。因此,在该机制中,当内核在执行中断的剩余工作时就处在进程上下文(process context)中。也就是说由工作队列所执行的中断代码会表现出进程的一些特性,最典型的就是可以重新调度甚至睡眠。

对于tasklet机制(中断处理程序也是如此),内核在执行时处于中断上下文(interrupt context)中。而中断上下文与进程毫无瓜葛,所以在中断上下文中就不能睡眠。

因此,选择tasklet还是工作队列来完成下半部分应该不难选择。当推后的那部分中断程序需要睡眠时,工作队列毫无疑问是你的最佳选择;否则,还是用tasklet吧。

中断上下文

在了解中断上下文时,先来回顾另一个熟悉概念:进程上下文(这个中文翻译真的不是很好理解,用“环境”比它好很多)。一般的进程运行在用户态,如果这个进程进行了系统调用,那么此时用户空间中的程序就进入了内核空间,并且称内核代表该进程运行于内核空间中。由于用户空间和内核空间具有不同的地址映射,并且用户空间的进程要传递很多变量、参数给内核,内核也要保存用户进程的一些寄存器、变量等,以便系统调用结束后回到用户空间继续执行。这样就产生了进程上下文。

所谓的进程上下文,就是一个进程在执行的时候,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容。当内核需要切换到另一个进程时(上下文切换),它需要保存当前进程的所有状态,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态继续执行。上述所说的工作队列所要做的工作都交给工作者线程来处理,因此它可以表现出进程的一些特性,比如说可以睡眠等。

对于中断而言,是硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理,中断上下文就可以理解为硬件传递过来的这些参数和内核需要保存的一些环境,主要是被中断的进程的环境。因此处于中断上下文的tasklet不会有睡眠这样的特性。

工作队列的使用

内核中通过下述结构体来表示一个具体的工作:

1
struct work_struct
2
{
3
unsigned long pending;//这个工作是否正在等待处理
4
struct list_head entry;//链接所有工作的链表,形成工作队列
5
void (*func)(void *);//处理函数
6
void *data;//传递给处理函数的参数
7
void *wq_data;//内部使用数据
8
struct timer_list timer;//延迟的工作队列所用到的定时器
9
};
而这些工作(结构体)链接成的链表就是所谓的工作队列。工作者线程会在被唤醒时执行链表上的所有工作,当一个工作被执行完毕后,相应的work_struct结构体也会被删除。当这个工作链表上没有工作时,工作线程就会休眠。

通过如下宏可以创建一个要推后的完成的工作:

1
DECLARE_WORK(name,void(*func)(void*),void *data);
也可以通过下述宏动态创建一个工作:

1
INIT_WORK(struct work_struct *work,void(*func)(void*),void *data);
与tasklet类似,每个工作都有具体的工作队列处理函数,原型如下:

1
void work_handler(void *data)
将工作队列机制对应到具体的中断程序中,即那些被推后的工作将会在func所指向的那个工作队列处理函数中被执行。

实现了工作队列处理函数后,就需要schedule_work函数对这个工作进行调度,就像这样:

1
schedule_work(&work);
这样work会马上就被调度,一旦工作线程被唤醒,这个工作就会被执行(因为其所在工作队列会被执行)。

时间: 2024-10-07 06:31:29

中断下半部-工作队列的相关文章

《Linux内核设计与实现》读书笔记(八)- 中断下半部的处理

在前一章也提到过,之所以中断会分成上下两部分,是由于中断对时限的要求非常高,需要尽快的响应硬件. 主要内容: 中断下半部处理 实现中断下半部的机制 总结中断下半部的实现 中断实现示例 1. 中断下半部处理 那么对于一个中断,如何划分上下两部分呢?哪些处理放在上半部,哪些处理放在下半部? 这里有一些经验可供借鉴: 如果一个任务对时间十分敏感,将其放在上半部 如果一个任务和硬件有关,将其放在上半部 如果一个任务要保证不被其他中断打断,将其放在上半部 其他所有任务,考虑放在下半部 2. 实现中断下半部

Linux内核源代码情景分析-中断下半部(软中断)

Tasklet机制是一种较为特殊的软中断.Tasklet一词的原意是"小片任务"的意思,这里是指一小段可执行的代码,且通常以函数的形式出现.软中断向量HI_SOFTIRQ和TASKLET_SOFTIRQ均是用tasklet机制来实现的.      从某种程度上讲,tasklet机制是Linux内核对BH机制的一种扩展.在2.4内核引入了softirq机制后,原有的BH机制正是通过tasklet机制这个桥梁来纳入softirq机制的整体框架中的.正是由于这种历史的延伸关系,使得taskl

linux内核是中断下半部

首先阐述下为什么内核要将中断分成上下半部 因为中断本身打断了正常的程序执行,中断中不能进行任务调度,所以中断需要快返回,但是某些操作必须在中断中执行. 如果内核需要执行一个硬件相关.时间敏感.不能被中断的操作,那么这些操作就应该放到上半部中,其他能够推迟的操作应该放到下半部中去,这样完成了中断中必须完成的操作,又能很好的进行调度. 看看内核对于下半部的支持 首先说以下如何添加自己的软中断程序 首先添加自己的软中断类型,值越低优先级越高 用open_softirq增加相对应的中断处理函数 用rai

【linux kernel】 中断处理-中断下半部

欢迎转载,转载时需保留作者信息,谢谢. 邮箱:[email protected] 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http://blog.csdn.net/xiayulewa     1.   概述 Linux内核中断机制:为了在中断执行时间尽可能短和中断处理需要完成大量工作之间找到一个平衡点,Linux将中断处理程序分解为两个半部,顶半部和底半部.       顶半部完成尽可能少的比较紧急的任务,它往往只是简单地读取寄存器中

Linux中断下半部tasklet机制

平台:Linux2.6.18 一,      软中断 1.1         在文件<linux/interrupt.h>中 1.1.1     当前内核用到的软中断类型 1 enum 2 { // HI_SOFTIRQ,TASKLET_SOFTIRQ为tasklet用软中断实现时用到的两个软中断 3 HI_SOFTIRQ=0, 4 TIMER_SOFTIRQ, 5 NET_TX_SOFTIRQ, 6 NET_RX_SOFTIRQ, 7 BLOCK_SOFTIRQ, 8 TASKLET_SOF

[linux内核]linux中断下半部分——工作队列

一:工作队列概念 工作队列可以把工作推后,交由一个内核线程去执行,工作队列运行在进程上下文中,工作队列运行重新调度甚至睡眠内核驱动程序一般将下半部分交给内核缺省的工作者线程去做 二:驱动中使用工作队列的步骤 1,声明一个work_struct结构体 [cpp] view plaincopy struct work_struct work; 2,动态创建一个由work指向的工作,处理函数为func [cpp] view plaincopy INIT_WORK(struct work_struct 

android 电容屏(二):驱动调试之基本概念篇

关键词:android  电容屏 tp 工作队列 中断 多点触摸协议平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV310(samsung exynos 4210)  作者:xubin341719(欢迎转载,请注明作者) 参考网站:http://edsionte.com/techblog/archives/1582这部分参考别人的多一点 android 电容屏(一):电容屏基本原理篇 android 电容屏(二):驱动调试之基本概念篇

linux中断的上半部和下半部 【转】

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=24690947&id=3491821 一.什么是下半部 中断是一个很霸道的东西,处理器一旦接收到中断,就会打断正在执行的代码,调用中断处理函数.如果在中断处理函数中没有禁止中断,该中断处理函数执行过程中仍有可能被其他中断打断.出于这样的原因,大家都希望中断处理函数执行得越快越好. 另外,中断上下文中不能阻塞,这也限制了中断上下文中能干的事. 基于上面的原因,内核将整个的中

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

目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管理 (3)workqueue工作队列> 关键词: 工作队列的原理是把work(需要推迟执行的函数)交由一个内核线程来执行,它总是在进程上下文中执行. 工作队列的优点是利用进程上下文来执行中断下半部操作,因此工作队列允许重新调度和睡眠,是异步执行的进程上下文,它还能解决软中断和tasklet执行时间过长导