Skip to content

中断和异常的处理

2026 大纲 一(三)2 中断和异常的处理

用户程序拿走了 CPU,OS 怎么把它要回来

上一节说清了 OS 的权威来自硬件给的模式位。但那里留下一个问题没答: OS 现在运行在用户态的程序手里,它怎么才能重新拿到 CPU?

它不能"主动去拿"——OS 自己也是代码,代码不执行就什么也做不了, 而此刻 CPU 正在执行用户程序。软件层面没有任何办法让一段不在运行的代码运行起来。 所以答案只能还是硬件:必须有一个机制,能在某些事件发生时强行打断当前指令流, 把 CPU 交给内核里一段指定的代码。 这个机制就是中断。

于是中断成了 OS 的驱动力,缺了它三件事都做不成:进不了内核态(用户程序拿到 CPU 就再也交不回来)、 无法抢占 CPU(一个死循环就锁死整机)、无法响应 I/O(只能轮询空耗)。 上一节讲的三条进内核的路——外中断、内中断、自愿性中断——其实是同一个机制的三种触发源。

这一节把这个机制拆开看:它怎么分类(按谁引发、按能不能恢复)、 一次中断从发生到返回都经过哪些步骤(哪些是硬件做的、哪些是 OS 做的)、 以及中断处理到一半又来一个中断怎么办

一、中断的分类

内中断按"能不能恢复、返回到哪"再分三类:

类型判据:这次异常是不是程序自己要的 / 能不能修复处理方式举例
陷入 Trap程序有意触发处理后执行下一条指令系统调用、断点
故障 Fault非本意,但可恢复修复后重新执行引起故障的指令缺页异常
终止 Abort非本意,且不可恢复终止进程,无返回点可言硬件故障、非法指令
中断技术的应用范围,以及另一套教材口径:按中断源分的五类中断事件(题干出现"程序性中断事件""自愿性中断事件"这类术语时展开)

中断的概念是怎么定型的。 中断技术最初仅作为设备向 CPU 报告 I/O 情况的手段,用来解决主机和设备的并行性问题;后来应用范围不断扩大,请求系统服务、实现并行工作、处理突发事件、满足实时要求都需要打断处理器的正常工作流程,中断的概念由此定型。

五类中断事件。 同一批事件,不同教材切法不同,两套说法都要认识。

中断事件典型来源处理原则对应到内/外中断口径
硬件故障中断事件电源故障、主存故障、总线奇偶校验错保护现场、停机、向操作员报告,估计并恢复破坏外中断中的不可屏蔽中断
程序性中断事件除数为零/溢出、非法指令、用户态使用特权指令、地址越界、非法存取、虚拟地址异常算术异常报告用户;非法指令/越界类终止进程;虚拟地址异常调整主存后重新执行指令内中断中的 Fault / Abort
自愿性中断事件(即系统调用程序执行陷入指令按功能号查系统调用入口表,执行服务例程,返回系统调用的下一条指令内中断中的 Trap
I/O 中断事件设备传输正常结束、故障、异常正常结束则唤醒等待进程;故障则取状态字分析原因外中断(可屏蔽)
外部中断事件时钟、间隔时钟(时间片到)、设备接入/结束、键鼠信号、关机重启计时;时间片到则被中断进程让出处理器进就绪队列外中断(可屏蔽)

能对上的部分:自愿性中断事件就是 Trap;程序性中断事件覆盖了 Fault 与 Abort;I/O 中断事件 + 外部中断事件就是可屏蔽外中断;硬件故障中断事件对应不可屏蔽外中断。

分歧在哪:Trap/Fault/Abort 三分法是按返回位置切的(下一条 / 重新执行当前条 / 不返回),五分法是按中断源切的。所以"程序性中断事件"内部同时含可恢复的(虚拟地址异常 → 重新执行指令)与不可恢复的(非法指令 → 终止进程),它并不是 Fault 的同义词。两套分类不是同一维度的替代品,遇到题干用哪套术语就答哪套。

二、中断响应与处理流程

最简单的指令执行分为取指、解码、执行三步。中断能被发现,靠的是在这三步之后加入了一个"检查中断"的微操作:处理器完成一个执行周期后先看中断是否被允许,不允许就继续执行下一条指令;允许则检查是否有中断出现,有则触发相应硬件电路。这一步同时解释了两件事——外中断为什么在"一条指令执行完毕后"才被检测,以及关中断为什么能挡住中断。

发现并响应中断的硬件装置称为中断装置,按中断源分三套:中断控制器(响应处理器外的异步事件,含记录来源的中断寄存器与中断逻辑电路)、系统陷入机制(由陷入指令触发,引向系统调用处理程序)、指令陷入机制(由指令的控制逻辑与实现电路触发,引向异常处理程序)。

分界记法:硬件负责"把控制权准确地送到该去的地方"(断点 + 入口地址),软件负责"把事情办完再原样还回去"(现场 + 处理逻辑)。

换一个更好用的判据:凡是要动 PC、PSW 这两个特殊寄存器或模式位的,都是硬件做的—— 因为这些动作发生时 CPU 还在用户态,权限根本不够,只能靠硬件的自动机制完成。 剩下那些"用普通指令就能做的事"(保存通用寄存器、查表、调用函数)才轮到 OS。

断点与现场是两件事,分属两端,最容易搞反:断点指 PC 和 PSW,由硬件保存; 现场指通用寄存器,由软件保存。

时刻要分清:中断"发生时"和处理程序"执行时"不是同一状态

这是同一条流程上两个相邻却不同的时刻,混起来就会答反。

时刻发生了什么CPU 处于哪一态
用户进程正常运行用户态
中断/异常发生通常仍是用户态——多数 I/O 中断、时钟中断、陷入、缺页都是在用户进程跑着的时候触发的
硬件响应:存断点、置模式位、取向量正在切换 → 内核态
中断处理程序开始执行必然是内核态
恢复现场,执行中断返回指令切回原态(多为用户态)

②和④的区别不在于"是不是内核态",而在于前者是触发切换的原因,后者是切换完成的结果。 说"中断发生时 CPU 处于内核态"是错的——如果它已经在内核态,那这次中断就不是从用户程序来的了。

哪些指令可能引起态切换

题目常给一条具体指令,问它执行时会不会导致用户态变内核态。判据有两条,沾上任意一条就"可能"

  1. 它本身是不是主动陷入指令trap / INT n / syscall)——是则必然切换;
  2. 它执行过程中是否可能触发异常——算术指令可能除零溢出、访存指令可能缺页或越界,都算"可能"。

两条都不沾的才是"绝不切换",而这类指令只有一种:不访存、不可能出异常的纯寄存器运算, 比如寄存器取非、同寄存器间的加法。

注意外中断不在这个判据里:它与当前执行的是哪条指令无关,不算"由这条指令导致"。

三、中断向量与中断向量地址

术语是什么存在哪
中断向量中断服务程序的入口地址(有的机器还含配套的 PSW)存放在中断向量表的表项里
中断向量地址该中断向量在中断向量表中的存放地址,即表项自身的地址由中断号(中断类型号)经硬件换算得到

完整链条:中断号 →(乘以表项长度加表基址)→ 中断向量地址 →(按此地址访存取出)→ 中断向量 → 送入 PC。说"中断向量地址就是中断服务程序入口"是错的,中间还差一次访存。

中断号   向量地址(表项)   表项内容 = 中断向量
  0    →  IVT+0×4    →  除零异常处理程序入口
  1    →  IVT+1×4    →  调试异常处理程序入口
 ...
 14    →  IVT+14×4   →  缺页异常处理程序入口
 ...
 32+   →  IVT+32×4   →  外设中断处理程序入口

采用这种"表驱动"而不是"逐个判断中断源"的方式,好处是定位入口的时间与中断源数量无关——不管有多少种中断,都是一次乘加加一次访存。

四、多重中断(中断嵌套)

单重中断多重中断(中断嵌套)
处理期间开不开中断全程关中断保护完现场后开中断
新到的高优先级中断只能等当前处理完立即打断当前中断处理程序
处理次序严格按到达先后先响应的可能被延后完成(后到的高优先级先做完)
现场保存在哪一层即可依次压入核心栈,返回时逆序弹出
代价高优先级事件响应慢,可能丢数据栈开销与实现复杂度上升

为什么必须允许嵌套:处理一个慢速 I/O 中断可能耗时很久,若此期间发生电源故障这类紧迫事件却不能立即响应,后果不可挽回。为什么又要限制嵌套:每嵌套一层就要在核心栈上多压一层现场,工程上一般以不超过三重为宜;处理过程中通常不响应 I/O 中断这类紧迫度不高的事件,也不响应与正在处理的中断同类的事件。

控制"谁能打断谁"靠两样东西:

  • 中断优先级:中断装置预设,原则是"以不发生中断丢失为前提"。一般由高到低为硬件故障中断 → 自愿性中断 → 程序性中断 → 外部中断 → I/O 中断,但各系统可不同(关机/重启中断在多用户系统里优先级最低,在个人计算机上却最高)。
  • 中断屏蔽字:处理程序用软件设置,三个用途——① 系统程序执行期间延迟或禁止某些中断,以免共享数据结构被破坏;② 保证高优先级能打断低优先级、反之不能;③ 处理某级中断时屏蔽该级中断本身,防止同级相互干扰。最简单的实现是屏蔽与自己同级和比自己低的,放行比自己高的
同一组事件在单重与多重下的两条时间线(想在时间轴上看清嵌套如何改变响应延迟与完成次序时展开)

设 I/O 中断处理程序需运行 100 μs,硬件故障中断处理程序需运行 20 μs,故障中断优先级更高。t=0 时 CPU 开始处理一个 I/O 中断,t=30 μs 时发生一次硬件故障中断,忽略中断响应本身的硬件开销。

单重中断。 判断能否被响应,第一件事永远是看当前中断是否开放,而不是看优先级——关中断的情况下优先级再高也进不来。单重系统全程关中断,t=30 到达的请求只能挂着等,直到 I/O 中断处理在 t=100 结束并开中断才被响应:

响应延迟 =10030=70 μs;I/O 中断在 100 μs 结束,故障中断在 100+20=120 μs 结束。

多重中断。 嵌套是否发生取决于两个条件同时满足:"中断已开放"且"新中断优先级高于当前屏蔽字放行的下限"。此处两条都满足 → 立即响应,响应延迟 =0。两条时间线:

  • t=30:I/O 中断的现场被压入核心栈,转去处理故障中断
  • t=50:故障中断处理完毕,逆序弹出现场,回到被打断的 I/O 中断处理程序继续
  • I/O 中断还剩 10030=70 μs 要跑,于是在 50+70=120 μs 结束

对照结论:嵌套只是把 CPU 时间"插队"给了高优先级中断,被打断者的剩余工作量一点没少,所以结束时刻整体后移了嵌套者的执行时间。多重中断把高优先级事件的响应延迟从 70 μs 压到 0,代价是 I/O 中断的完成时刻从 100 μs 推到 120 μs,并且改变了完成次序——先响应的反而后完成

五、中断与进程切换的关系

中断处理结束时并不总是回到被中断的那个进程。中断返回前,OS 会检查是否需要重新调度

情形中断返回后为什么
一次普通的系统调用(如 getpid回到原进程原断点没有任何进程状态发生变化
时钟中断且当前进程时间片用完切换到另一进程时间片到 ⇒ 被中断进程让出处理器进入就绪队列 ⇒ 触发调度
I/O 完成中断唤醒了一个更高优先级进程抢占式系统下切换就绪队列里出现了比当前进程更该运行的进程
缺页故障调页期间当前进程阻塞,切换;调页完成后重新执行原指令调页要访问磁盘,不能让 CPU 干等

时钟中断是抢占式调度得以成立的物理基础:正因为时钟会周期性地把控制权强行夺回内核,OS 才有机会重新做调度决定。没有时钟中断,一个不主动放弃 CPU 的进程将永远占据处理器。切换的具体动作(保存/恢复上下文)见上下文及其切换机制

中断这个主题在操作系统与计算机组成原理里各关心什么(想弄清本文的边界时展开)
维度操作系统视角(本文)计算机组成原理视角
关心什么OS 如何夺回控制权、切换内核态、是否引发进程切换硬件如何识别中断信号、中断隐指令的组成、优先级判别电路
典型对象进程、PCB、内核态/用户态、系统调用流程、屏蔽字的策略含义向量地址形成电路、屏蔽字的赋值时机与排队器实现、中断响应周期时序

中断隐指令的微操作时序、屏蔽字寄存器的硬件实现属于硬件层面,本文点到即止。

考点速记

  1. 广义中断分外中断(异步、指令执行完毕后检测)与内中断/异常(同步、指令执行过程中检测);内中断按返回位置分 Trap(下一条)/ Fault(重新执行当前条)/ Abort(终止),缺页属 Fault。另一套口径按中断源分五类,与前者切在不同维度上。
  2. 软硬件分界的好用判据:要动 PC / PSW / 模式位的都是硬件,用普通指令做得成的才是 OS。断点(PC、PSW)由硬件存,现场(通用寄存器)由软件存
  3. 中断"发生时"通常仍在用户态,处理程序"开始执行时"必然在内核态——前者是原因,后者是结果。
  4. 判断一条指令会不会引起态切换:是不是主动陷入指令 + 执行中可不可能触发异常,两条都不沾的纯寄存器运算才"绝不切换"。
  5. 定位入口走中断号 → 向量地址 → 向量 → PC中断向量地址不是入口地址,中间差一次访存;表驱动使耗时与中断源数量无关。
  6. 单重中断全程关中断,多重中断保护完现场即开中断,靠优先级(设计时定死)+ 屏蔽字(运行时设置)共同决定谁能打断谁。
  7. 中断必然进内核态,但不必然引起进程切换——只有 OS 决定重新调度时才切。反过来"进程切换必然发生在内核态"成立。

这一节在真题里被考过的形式

出题密度高,且几乎全在"分界"上做文章——软件与硬件的分界、两个时刻的分界、 库函数与系统调用的分界。记住分界,题就没有难度。

  • 给三件事,问哪些会导致用户态切到内核态(2013-28)。答整数除以零 + read 系统调用sin() 不切换。分界是"这件事用户态能不能自己完成"——算正弦值能,所以 sin() 全程在用户态;访问文件系统不能,所以 read 必须陷入。⚠️ 库函数不是系统调用,C 标准库里大部分函数根本不进内核。
  • 给四条具体指令,问哪条不可能导致态切换(2015-24)。答 NOT R0INT n 是主动陷入必然切;DIV 可能除零;MOV R0, addr 可能缺页;只有纯寄存器取非两条判据都不沾。⚠️ 这道题问的是"不可能",要逐条找出"有没有任何一条路径能引出切换",漏想缺页就会误选 D。
  • 问系统调用过程中哪些操作由操作系统完成(2022-31)。答保存通用寄存器 + 执行系统调用服务程序。保存断点和 PSW、把模式位改成内核态这两件都是硬件做的。⚠️ 这道题就是"要动 PC/PSW/模式位的都是硬件"这条判据的直接考法。
  • 判断中断和异常的四条叙述,选错误的(2024-23)。错项是"中断或异常发生时,CPU 处于内核态"——发生的那一瞬间通常还在用户态。同题的 C 项"中断处理程序开始执行时 CPU 处于内核态"是对的。⚠️ A 与 C 只差"发生"和"开始执行"两个词,是本节被利用得最狠的一处时刻差。

复习优先级必须拿满,且这一节的判据在系统调用那篇会原样再用一遍。 Trap/Fault/Abort 的返回位置、软硬件分工、两个时刻的差别,这三处每一处都单独出过题。 多重中断的时间线计算至今没进过选择题,但它是理解屏蔽字的必要一步,读懂即可。

易错:说"中断发生时 CPU 处于内核态"。发生的那一刻通常仍在用户态;处理程序开始执行时才必然在内核态。

易错:把库函数调用当成系统调用。sin() 这类纯计算函数全程在用户态,不引起任何切换。

易错:把"中断向量地址"当成中断服务程序入口。向量地址是表项自身的地址,按它访存取出来的才是入口地址。

易错:把保存断点和保存现场混为一谈。断点(PC、PSW)由硬件保存,现场(通用寄存器)由软件保存

易错:认为访存指令不可能引起态切换。它可能缺页或越界,属于"可能"。

易错:由"中断必然进内核态"推出"中断必然引起进程切换"。普通系统调用返回后仍是同一进程。

易错:认为一开头就关中断所以不可能嵌套。那描述的是单重中断;多重中断在保护完现场之后会重新开中断。

教材出处
  • 孙钟秀、费翔林《操作系统教程》(第 6 版)2.2.1 中断的概念(p44~p45):"可以说操作系统是由中断驱动的";广义中断划分为狭义中断、异常和系统异常三大类。
  • 同书 2.2.2 中断源(p45~p47):五类中断事件(硬件故障中断、程序性中断、自愿性中断、I/O 中断、外部中断)及各自的处理原则,包括"非法指令、用户态使用特权指令、地址越界、非法存取等指令异常:终止进程"与"虚拟地址异常:……需要调整主存后重新执行指令"。
  • 同书 2.2.3 中断系统(p47~p48):指令执行周期后加入"检查中断"的微操作;中断装置分为中断控制器、系统陷入机制与指令陷入机制三类。
  • 同书 中断屏蔽与中断优先级、多重中断事件处理(p51~p52):中断屏蔽的三个用途;中断优先级"一般来说……依次为硬件故障中断、自愿性中断、程序性中断、外部中断和 I/O 中断",且不同系统可不同;"中断嵌套处理一般以不超过三重为宜";"中断嵌套处理改变了中断处理的先后次序,先响应的中断反而被延后处理"。
  • 同书 2.1 处理器·用户栈和核心栈(p44):核心栈"保存中断现场,对于嵌套中断,将被中断程序的现场信息依次压入核心栈,中断返回时逆序弹出"。

相关知识

CPU运行模式(内核态与用户态)系统调用上下文及其切换机制

真题练习