内核基础层提供的服务---软中断和tasklet 、 工作队列

来源:互联网 发布:二手交易软件排名 编辑:程序博客网 时间:2024/06/05 16:19

1.1.3 软中断和tasklet

Linux内核把对应中断的软件执行代码分拆为两个部分:

和硬件关系紧密,这部分代码必须关闭中断来执行,以免被后面的中断打断,影响后面代码的执行---这部分代码在中断的上下文中执行;

另一部分和硬件关系不紧密,可以打开中断执行,这部分代码放在软中断上下文执行;

这种划分是一种初略的划分:

中断是计算机系统的宝贵资源关闭中断意味着系统不响应中断,代价过高。为了避免关闭中断的不利影响,即使在中断的上下文中,很多代码的执行也是打开中断的。

在软中断上下文中,甚至进程上下文的内核代码中,有的时候也需要关闭中断。


linux内核定义了几个默认的软中断,网络设备有自己的发送和接收软中断,块设备也有自己的软中断。

内核还定义了一个tasklet软中断:tasklet是一种特殊的软中断,同一时刻一个tasklet只能有一个CPU执行,不同的tasklet可以在不同的CPU上执行。

这和软中断不同,软中断可以同一时间可以在不同的CPU上执行---软中断需要考虑重入的问题

内核中很多地方使用了tasklet。

分析例子:

static DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet,hil_mlcs_process, 0);

tasklet_schedule(&hil_mlcs_tasklet);

上面的例子,首先定义了一个tasklet,他的执行函数是hil_mics_process.当程序中调用tasklet_schedule,会把执行的结构插入到一个tasklet链表,然后触发一个tasklet软中断。每个CPU都会有自己的tasklet链表,内核根据情况确定执行的tasklet。


继续添加:

http://blog.csdn.net/suiyuan19840208/article/details/8444982

http://blog.sae.sina.com.cn/archives/4103

http://blog.sina.com.cn/s/blog_7880d3350102v182.html

http://blog.csdn.net/eleven_yy/article/details/8050964

http://bbs.chinaunix.net/thread-4167406-1-1.html




1.1.4 工作队列

工作队列和tasklet相似,也是一种延缓执行的机制。

不同之处是工作队列有自己的进程上下文,所有工作队列都可以睡眠,也可以被调度tasklet不可睡眠】


以下代码是工作队列的例子:


工作队列很简单,schedule_work把用户定义的work_struct加入系统的队列中,并唤醒系统线程去执行。

内核初始化的时候,创建一个工作队列keventd_wq,同时为这个工作队列创建内核线程【默认是为每个CPU创建一个内核线程】。这个线程去执行用户的work_struct。

内核还提供了create_workqueue和create_singlethread_workqueue函数,这样用户可以创建自己的工作队列和执行线程,而不是内核提供的工作队列。

看内核的例子:


int kblockd_schedule_work(struct request_queue *q, struct work_struct *work){return queue_work(kblockd_workqueue, work);}EXPORT_SYMBOL(kblockd_schedule_work);

queue_work函数进行工作队列的排队。

/** * queue_work - queue work on a workqueue * @wq: workqueue to use * @work: work to queue * * Returns 0 if @work was already on a queue, non-zero otherwise. * * We queue the work to the CPU on which it was submitted, but if the CPU dies * it can be processed by another CPU. */int queue_work(struct workqueue_struct *wq, struct work_struct *work){int ret;ret = queue_work_on(get_cpu(), wq, work);put_cpu();return ret;}


kblockd_workqueue是内核通用模块提供的工作队列,需要由kblockd_qorkqueue执行的工作就要调用kblock_schedule_work,其实就是调用queue_work把work插入到kblock_workqueued的任务列表。


阅读全文
0 0