原文出处:http://blog.csdn.net/wq897387/article/details/7495506
为什么会出现顶半部和底半部中断机制呢?
我们知道当中断触发的时候,CPU会响应处理,当要处理的事情很多的时候(比较耗时),CPU将会被一直占用,从而导致其它的进程不能正常运行,因此就用顶半部来处理较快的中断部分,底半部用来处理较耗时的部分。这样就不会存在CPU一直被耗时的中断处理占用的情况。
softirq,tasklet,workqueue
软中断和tasklet仍然运行于中断上下文,而工作队列则运行于进程上下文
实现的过程:
1.“顶半部”:是实际响应中断的例程(request_irq 注册的那个例程)。
2.“底半部”:是被顶半部调度,并在稍后更安全的时间内执行的函数
//tasklet使用模板
tasklet将任务延迟到安全时间执行
void xxx_do_tasklet(unsigned long);
DECLARE_TASKLET(xxx_tasklet,xxx_do_tasklet,0);
void xxx_do_tasklet(unsigned long)
{
…………
}
irqreturn_t xxx_interrupt(int irq,void *dev_id,struct pt_regs *regs)
{
…………………
tasklet_schedule(&xxx_tasklet);
………………….
}
int __init xxx_init(void)
{
……………..
result=request_irq(xxx_irq,xxx_interrupt,SA_INTERRUPT,”XX”,NULL);
………………
}
void __exit xxx_exit(void)
{
…………………
free_irq(xxx_irq,xxx_interrupt);
…………………
}
//工作队列使用模板
struct work_struct xxx_wq;
void xxx_do_work(unsigned long);
void xxx_do_work(unsigned long)
{
………………..
}
irqreturn_t xxx_interrupt(int irq,void *dev_id,struct pt_regs *regs)
{
…………….
schedule_work(&xxx_wq);
……………….
}
int xxx_init(void)
{
…………….
result=request_irq(xxx_irq,xxx_interrupt,SA_INTERRUPT,”xxx”,NULL);
……………..
INIT_WORK(&xxx_wq,(void ()(void )) xxx_do_work,NULL);
……………..
}
void xxx_exit(void)
{
……………
free_irq(xxx_irq,xxx_interrupt);
…………….
}
软中断和tasklet仍然运行于中断上下文,而工作队列则运行于进程上下文。因此,软中断和tasklet处理函数中不能睡眠,而工作队列处理函数中允许睡眠。
local_bh_disable()和local_bh_enbale()是内核中用于禁止和使能 中断和tasklet底半部机制的函数