中断
硬中断和软中断的定义与区别
硬中断(Hardware Interrupt)
定义:
由外设硬件发出的中断信号,如网卡、磁盘、键盘、定时器等,通知 CPU “我有事情需要处理”。
特点:
- CPU 接收到硬件的 IRQ(中断请求),立刻打断当前任务,转去执行内核中对应的中断服务程序(ISR,Interrupt Service Routine)。
- 每个设备的 IRQ 是唯一的,中断控制器(如 APIC)会告诉 CPU 哪个中断发生了。
- 多核系统中,中断通常被分发到某一核上处理。
- 时钟中断用于进程调度。
- ISR 是在原子上下文中执行的(不可休眠、不可阻塞)。
软中断(Software Interrupt)
定义:
是内核中的一种推迟处理机制,用于完成一些不能在硬中断中完成的耗时操作(如网络包处理、协议栈处理等)。
特点:
- 不由硬件发出,而是由内核代码主动触发,或者在硬中断中注册。
- 是一种“推后执行”的中断,执行时机由内核控制。
- 是为了减轻硬中断处理时间的压力。
- 软中断并不打断当前进程,而是等内核空闲或调度器合适时再处理。
硬中断与软中断的区别总结
项目 | 硬中断 | 软中断 |
---|---|---|
产生方式 | 外设(如网卡、磁盘)主动发送IRQ | 内核代码主动触发 |
是否可屏蔽 | 可屏蔽 | 不可屏蔽 |
中断号来源 | 中断控制器 | 由程序指令指定 |
是否打断当前任务 | 会打断当前运行任务 | 不会打断,推后执行 |
执行上下文 | 原子上下文(不能阻塞) | 中断上下文(不能睡眠) |
用途 | 快速处理设备请求 | 完成硬中断不能完成的任务 |
上半部和下半部机制详解
为什么要分为上半部和下半部?
- 中断必须尽快响应:否则会丢失数据或影响实时性;
- 中断处理不能太慢:否则会阻塞其他中断或任务调度;
- 因此将中断处理拆成两部分:
- 上半部(硬中断):快速完成必要操作,比如读取设备状态、保存数据等;
- 下半部(软中断、tasklet等):处理复杂、耗时、可延迟的任务。
上半部
- 执行时间短,处理紧急、关键操作;
- 在中断上下文中执行;
- 不允许阻塞或调用可能阻塞的函数;
- 优先级高。
下半部
- 执行时间长,处理缓慢任务;
- 可以被打断;
- 优先级低;
- 有多种实现方式:软中断、tasklet、工作队列。
下半部的三种实现机制
类型 | 特点 | 执行上下文 | 是否可睡眠 | 适合场景 |
---|---|---|---|---|
软中断(softirq) | 静态注册、可并发执行 | 中断上下文 | ❌ | 网络子系统等高性能场景 |
tasklet | 基于软中断的封装、串行执行 | 中断上下文 | ❌ | 中等复杂度任务 |
工作队列(workqueue) | 可以休眠、调度 | 进程上下文 | ✅ | 需要调度、I/O 等任务 |
Linux中断响应执行流程(简化版)
外设产生中断 →
中断控制器(APIC)发送中断号 →
CPU接收中断号 →
进入中断处理程序(ISR,上半部) →
注册下半部任务(如软中断) →
返回执行正常任务 →
内核稍后调度执行下半部 →
中断处理完成
中断处理函数何时执行?中断的申请位置?
- 中断的处理函数注册通过:
request_irq()
完成; - 正确注册位置通常是设备第一次被打开的时候;
- 注意:在调用
request_irq()
之前必须确保硬件已经初始化完毕,否则中断可能来不及处理。
小结
- 硬中断来自硬件,优先级高、处理快;
- 软中断是内核机制,用于“推后处理”;
- 上下半部机制让中断处理更高效;
- request_irq() 需要在设备使用前完成调用;
- 下半部可以用 softirq、tasklet、workqueue,各有适用场景。