当前位置: 首页 > Linux kernrl > 正文

Linux 中断之下半部机制

前言

有些事情开了就等于跳悬崖了。   中断之下半部机制。

__start

下半部的机制还是因为中断上下文不可以睡眠,并且内核需要它快速响应所以,将它分成了两个部分,一个是前半部,一个是下半部。

中断处理程序以异步的方式执行,并且它有可能会打断其他重要的代码的执行。因此为了避免被打断代码停止时间过长。中断处理程序应该执行的越快越好。就像前面所说的,中断处理程序往往需要对硬件进行操作,所以有很高的时限要求。并且不能在进程上下文中运行因为他们不可以被打断。

上半部的要求

如果一个任务对时间非常敏感,将其放在中断处理程序

如果一个任务和硬件相关,将其放在中断处理程序中执行

如果一个任务要保证不被其他中断打断,将其放在中断处理程序中执行。

其他所有任务,考虑放置在下半部执行

使用下半部的原因

唯一的原因就是提高系统的响应能力,提高系统的性能。

下半部的环境

下半部现阶段有三个机制:工作队列,软中断,tasklet.

其实tasklet 是基于软中断实现的,而工作队列是另一退后的方式。

几种推后机制的区别

首先对比软中断与tasklet .

软中断:系统级别的静态编译的程序,不能动态的注册或注销,擅长处理高并发的中断,比如网卡。它有32个接口,可以在所有处理器上同时执行,即使两个类型相同也可以。

tasklet:  这是基于软中断的一种灵活的实现,它是动态的可分配的,两个不同的tasklet 可以在不同的处理器上同时执行,但是类型相同的tasklet 不能同时执行。由此可见这其实又是一种折中的产物。但是他可以动态的注册。使用性较强。

比较这两种机制的异同:

相同之处:执行环境都在中断上下文,这就保证了他们都是不能中断的。

不同之处:tasklet 同类型不能同时执行

工作队列:另一种推后机制,工作队列可以把工作推后,交由一个内核线程执行这个下半部分总是在进程的上下文中执行。它是唯一能在进程上下文中运行的下半部实现机制。它和之前的两个东西不同,它是在进程上下文中的,是和进程上下文一样被调度的。

一个tasklet 的模块实例


#include<linux/module.h>
#include<linux/init.h>
#include<linux/interrupt.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zmrlinux");
MODULE_DESCRIPTION("tasklet");

unsigned long dev = 1;
void my_tasklet_handler(unsigned long data);

//DECLARE_TASKLET(my_tasklet,my_tasklet_handler,dev);

void my_tasklet_handler(unsigned long data){
int i = 10;
while(i > 0){
printk("hello world\n");
i--;
}
}
struct tasklet_struct my_tasklet;
static int __init test_task(void){
tasklet_init(&my_tasklet,my_tasklet_handler,dev);
tasklet_schedule(&my_tasklet);
printk("hello world\n");
return 0;
}

static void __exit test_out(void){
printk("ByBy\n");
}

module_init(test_task);
module_exit(test_out);

执行结果:

2015-12-01 12:32:38 的屏幕截图

本文固定链接: http://zmrlinux.com/2015/12/01/linux-%e4%b8%ad%e6%96%ad%e4%b9%8b%e4%b8%8b%e5%8d%8a%e9%83%a8%e6%9c%ba%e5%88%b6/ | Kernel & Me

该日志由 root 于2015年12月01日发表在 Linux kernrl 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Linux 中断之下半部机制 | Kernel & Me