背景
什么是中断上下半部?
简而言之,就是把中断分为两个部分执行。一部分紧急的任务在中断处理函数中执行,称为上半部。另外一部分(也紧急,但是需要相对较多的时间处理,相对没那么紧急)在中断函数外由操作系统调用执行,称为下半部。
为什么需要中断上下半部?
假设没有中断下半部,这时中断发生了,在其中需要处理一些事情,这个事情如果比较急处理,而且占用的时间比较长,那么cpu就会待在中断中的时间比较长,这样就会影响其他进程的调度,导致整个操作系统的执行效率就比较低。而如果加入了中断下半部,把中断中紧急的事情再分成 很紧急 紧急 两个级别。然后把很紧急的事情,放在中断中快速处理完后退出,让出CPU使用权(退出前向操作系统注册一个下半部处理),其他紧急内容留到中断下半部中处理。在退出中断后操作系统会根据当前的情况来调用中断下半部或者其他更紧急的进程。这样就使得整个系统效率更高。
中断上下半部的两个策略
tasklet
(1)tasklet机制的目的
tasklet机制的引入,主要是考虑到支持SMP,提高SMP多个cpu的利用率(不同的tasklet可以在不同的cpu上运行)。
(2)tasklet机制的特点
tasklet属于中断上下文,因此不能被阻塞,不能睡眠,不能被打断
workqueue
(1)workqueue机制的特点
workqueue的突出特点是下半部会交给worker thead,因此下半部处于进程上下文,可以被重新调度,可以阻塞,也可以睡眠。
(2)workqueue的初始化方式
静态初始化:调用宏DECLARE_WORK,初始化中断的上半部,然后在中断上半部调用schedule_work()来启动中断下半部 。
动态初始化:调用宏INIT_WORK,初始化中断的上半部,然后在中断上半部调用queue_work()启动我们的中断下半部 。