跳转至

中断

中断(Interrupt)是计算机系统中一种重要的硬件机制,允许外部设备或内部事件请求CPU暂停当前执行的程序,转而处理紧急事件。中断和硬件密不可分,但是网上很多文章在介绍时会忽略这一点。下面介绍的都是x86/64。

可以从同步和异步的角度对中断进行分类:

  • 中断(Interrupt) 是异步的,通常由外部设备触发,与当前正在执行的指令无关。
  • 异常(Exception) 是同步的,由当前执行的指令导致。
    • 故障(Faults):​​ 在指令执行​​之前​​或​​期间​​检测到的可纠正错误(例如页面错误#PF)。处理程序修复问题后,CPU通常会​​重新执行​​导致故障的指令。
    • ​陷阱(Traps):​​ 在指令执行​​之后​​有意触发的异常(例如INT n软件中断、断点异常INT 0x3)。处理程序执行后,CPU继续执行​​下一条​​指令。
    • ​中止(Aborts):​​ 严重的、通常不可恢复的错误(例如硬件故障、系统表结构损坏)。通常导致进程或系统终止。

另外,int 0x80syscall指令都用于系统调用。后者的overhead更小,具体为什么这里就不细究了,可以简单的理解int 0x80需要硬件通用的中断处理,syscall有硬件专门的系统调用处理。

[!NOTE] “中断”在广义上包含异常,但狭义上特指外部中断。这里的翻译很容易混淆。 在RISCV中,又是 Trap 分成 Interrupt 和 Exception。所以在看相关资料的时候,一定要搞清楚上下文,到底在讨论什么硬件。

发生中断之后,硬件会保存一些上下文,并将PC转到对应的处理函数。那么硬件肯定要提供一个机制,供上层(一般就是OS)指定处理函数的地址。在x86中这涉及到IDT

软中断 (Soft IRQ)

软中断不是软件中断,而是Linux中对中断处理的一种模式。当一些中断并不需要立即处理的时候,内核可以将他们的处理逻辑延后执行。思路大体如下:

在处理硬(件)中断的时候,先进入一个简短的处理函数,设置一些必要的状态之后将后续的处理逻辑放在工作队列中。系统会在之后,从工作队列中取出待处理的中断,继续完成中断的处理。也就是将完整的中断处理逻辑分成了上部分和下部分

  1. 上部分会打断CPU原本正在执行的任务,耗时短,快速执行后返回。
  2. 下部分以内核线程的方式运行,负责上部分未完成的工作,通常是耗时较长的事情,延迟执行。

参考链接