大家好,我是王鸽,今天这篇文章主要什么是硬中断(Hard IRQ)和软中断(Softirq)?硬中断和软中断差异点使用的注意点等。一句话总纲
硬中断:硬件触发,快、短、不能阻塞,只做最紧急的事。软中断:内核触发,慢一点、可稍复杂,做耗时但必须实时的事。
一、来源不同
1. 硬中断 Hard IRQ
来自硬件:GPIO、UART、SPI、I2C、网卡、定时器…,硬件中断 = 外设引发。电平 / 边沿变化 → 发送电信号到GIC(中断控制器)→ 发给 CPU2. 软中断 Softirq
二、执行环境与上下文
硬中断
- 运行在中断上下文(Interrupt Context)
软中断
硬件中断(最快、不能睡) → 软中断(稍慢、仍不能睡) → tasklet(更慢、仍不能睡) → workqueue(最慢、可以随便睡)
三、执行时机与优先级
硬中断来了立即抢 CPU任何进程都要停,必须越快越好
软中断
硬中断处理完马上执行或者被 ksoftirqd 内核线程调度
四、硬中断 → 软中断 标准流程(最经典模型)
1. 硬件触发 → 进入硬中断
2. 硬中断处理:
读寄存器清中断不处理数据!只标记“有数据”触发软中断:raise_softirq(NET_RX_SOFTIRQ)
3. 硬中断退出
4. 软中断立刻执行
为什么要分两段?
硬中断慢 →系统所有中断被阻塞→ 网卡丢包、串口丢数据、系统卡顿五,硬中断 vs 软中断 对比表
| | |
|---|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| request_irq () 注册的 handler | open_softirq() + raise_softirq() |
注意点:
1. 驱动里写硬中断一定要快
不要在硬中断里做:大量数据拷贝循环处理udelay 很久互斥锁、等待队列
2. 软中断不能休眠
msleepmutexcopy_from_user / copy_to_user
另外tasklet 本质就是软中断,它只是软中断封装出来的 “易用版”。只有 workqueue 是进程上下文,只有它能 mutex、能 msleep、能 copy_to_user。3. 软中断执行慢会导致什么?
ksoftirqd占用 CPU 高系统响应变慢网络延迟增大定时器任务过多
最简单记忆口诀
硬件来了进硬中断, 只清标志不处理;
触发软中断延后做, 数据处理慢慢磨。
六、典型用途(嵌入式 Linux 必背)
硬中断典型动作
然后触发软中断 NET_TX_SOFTIRQ / NET_RX_SOFTIRQ
1. 网卡收到数据包 2. 触发硬中断 → CPU 立即响应3. 硬中断处理函数(快速处理): - 读取数据到内存 - 禁用当前中断线 - 触发 NET_RX_SOFTIRQ 软中断 - 退出硬中断 4. 稍后执行软中断: - 处理协议栈(IP/TCP 解析) - 将数据传递给应用程序 - 重新启用中断线
查看中断信息
查看硬中断统计
查看软中断统计
$ cat /proc/softirqs CPU0 CPU1 HI: 230791 236534 TIMER: 2545835 1771415 NET_TX: 142977 5230 NET_RX: 12253 15022 BLOCK: 76179 79134 IRQ_POLL: 0 0 TASKLET: 1041303 1052558 SCHED: 5185278 4713295 HRTIMER: 0 0 RCU: 2805029 2787349
查看中断分布(按CPU)
cat /proc/stat | grep cpucpu 458174 0 1087941 53255128 35415 0 14639 0 0 0cpu0 229525 0 544483 26624211 17867 0 7348 0 0 0cpu1 228649 0 543458 26630916 17547 0 7291 0 0 0
其实硬中断像是急诊室医生(立即处理紧急情况),软中断像是门诊医生(处理排队的一般问题)。这种分离确保了系统既能快速响应硬件事件,又能高效处理复杂任务。
谢谢点赞阅读收藏!