Appearance
程序查询方式与程序中断方式
2026 大纲 六(三)1 程序查询方式、六(三)2 程序中断方式(中断的基本概念、中断响应过程、中断处理过程、多重中断和中断屏蔽的概念)。
忙等不是停机,是空转
程序查询方式里,CPU 启动设备之后就守在那儿反复读状态位,直到设备说"好了"。这段时间常被说成"CPU 在等",但机器里并不存在"等"这个动作——CPU 一刻没停,它在满负荷地取指、译码、执行,跑的是一个 读状态 → 没就绪 → 跳回去再读 的死循环。指令一条不少地执行了,对程序的贡献是零。
这一点决定了查询方式的病根不在"每次查询很贵"上。把查询程序优化到只剩三条指令,CPU 照样要在那儿转到设备就绪为止——根本问题是外设准备数据的那一整段时间里,CPU 与外设是串行工作的,而这段时间由设备的物理速度决定,软件优化不掉。
于是改进方向被逼了出来:别让 CPU 去问,让设备准备好了自己来说。 这就是程序中断方式。它把那条轮询循环整个删掉,CPU 启动设备后转去跑别的程序,设备就绪时主动发中断请求,CPU 在一条指令执行完毕时响应、搬走数据、再回到原来的地方。外设与 CPU 从串行变成并行——这是中断方式相对查询方式的全部收益。
这里有一处最容易记反:中断方式并没有减少 I/O 占用的 CPU 时间。两种方式算占比的公式骨架完全相同,分子只是把"每次查询的周期数"换成"每次中断的周期数",而一次中断通常比一次查询更贵——它多出了保存断点、保护现场、恢复现场、中断返回这四段。省下来的是外设准备数据期间那一大段等待,不是每次介入的开销。
也正因为一次中断有固定的、压不下去的开销,中断方式有一条硬性的物理前提:
违反它的后果不是"慢",而是丢数据——上一个数据还没被中断服务程序搬走,设备已经把下一个覆盖上去了。设备越快,左边越小;而右边由中断机制本身决定,几乎不随设备变化。两条线一交叉,中断方式就彻底出局,只能改用 DMA。本篇最后一节就是在算这条线。
交互可视化
一、程序查询方式
最简单的一类外设不需要问状态:开关、继电器、七段数码管、机械式传感器随时可读可写,程序在约定的时刻用 I/O 指令读写数据端口即可,这叫无条件传送。但绝大多数设备做不到"随时就绪"——打印机在打上一个字符,磁头还在移动,键盘等着人按下去。对这类设备传送之前必须先确认条件成立,于是接口里多出一个状态寄存器,程序先读状态、再决定动作,这就是条件传送,也就是程序查询方式。
一次完整的输入握手因此长成六步:
- CPU 执行 I/O 指令送出"启动"命令,地址译码选中本接口 → 命令触发器置 1、状态触发器清 0
- 接口通过电缆向外设发"启动设备"命令
- 外设准备好一个数据,送入接口的数据缓冲寄存器
- 外设回送"设备工作结束"信号 → 状态触发器置 1、命令触发器清 0
- CPU 反复读状态端口,直到读到"准备就绪"
- CPU 执行 I/O 指令,从数据端口把数据取走
第 5 步就是"查询"二字的全部含义:CPU 用执行指令的方式,反复去读一个位。
忙等循环长什么样:把"空转"落到具体是哪几条指令在跑(想弄清"忙等不是停机"这句话的字面含义时展开)
开始:
CPU 向设备发出启动命令
循环:
读状态端口
if (未就绪)
goto 循环 // 忙等待:执行了指令,但没有任何有效产出
else
从数据端口取一个数据
if (还有数据)
goto 循环
else
结束注意那条 goto 循环:CPU 一直在取指、译码、执行,流水线满负荷运转,但产出为零。这就是"忙等不是停机,是空转"的字面含义——它和 CPU 停机(如停止 CPU 访存的 DMA 方式)在功耗与总线占用上完全不同,只是对程序的贡献同样为零。
按"查询由谁触发、查完做什么"分成两种模型:
| 模型 | 含义 | CPU 与外设的关系 | CPU 占比 |
|---|---|---|---|
| 独占查询 | 设备一被启动,CPU 就一直查下去直到传送完成 | 完全串行 | 100% |
| 定时查询 | 周期性地去查一次接口状态,条件满足就传一个数据然后返回 | 查询的那些瞬间串行 | 要算,见下式 |
两种模型的 CPU 开销完全不是一回事,而题面总会把用的是哪一种交代清楚——出现"CPU 循环等待直到就绪""期间不执行其他程序"就是独占查询,占比直接是 100%,没什么可算的;出现"每隔
定时查询的查询间隔由设备的数据传输率倒推:
式子里
还有两处方向性的口径要一并钉住。其一,查询间隔的不等号别写反:间隔必须
开销随设备速度线性上涨——设备快一倍,查询次数就翻一倍。改进方向也就被逼了出来:不要让 CPU 去问,让设备准备好了自己来说。
二、程序中断方式
中断方式对上面那条通路只改了一处:第五步的轮询被删掉了。CPU 启动设备后不再等待,直接切去执行别的程序(在操作系统看来是把发起 I/O 的进程阻塞、调度另一个进程上 CPU)。设备准备好一个数据后主动发中断请求,CPU 在当前指令执行结束时响应,转去执行中断服务程序,搬走数据并启动下一次传送,然后返回被打断的程序。
于是外设与 CPU 从串行变成并行。接口为此增加的是中断请求触发器与中断屏蔽触发器,以及送回中断类型号的电路;状态寄存器并没有消失,只是 CPU 不再靠"反复读它"来推进流程。开销公式的骨架与查询方式完全一样:
其中
三、一次中断从头走到尾
| 阶段 | 谁在做 | 做什么 |
|---|---|---|
| 中断请求 | 接口硬件 | 设备就绪 → 状态触发器置 1;若未被屏蔽(MASK |
| 中断判优 | 排队器(硬件)或轮询程序(软件) | 多个 INTR 同时为 1 时,按响应优先级选出一个 |
| 中断响应 | 硬件(中断隐指令) | 关中断 → 保存断点 → 形成入口地址送 PC |
| 中断服务 | 软件(中断服务程序 ISR) | 保护现场 → 设备服务(把数据搬走)→ 恢复现场 |
| 中断返回 | 软件 | 一条中断返回指令回到断点,原程序继续 |
软硬件的分界画在第三与第四阶段之间,这条分界不是约定俗成——第三阶段要保存断点,而此刻软件根本还没拿到控制权,只能由硬件做。
| 由什么决定 | 能否改 | 管的是什么 | |
|---|---|---|---|
| 响应优先级 | 硬件排队器的连线次序 | 不能 | 同时提出请求时,先响应谁 |
| 处理优先级 | 中断屏蔽字 | 能,由软件改 | 已经在处理的中断,能被谁打断 |
这张表划出了一条常被跨过去的界线:中断屏蔽字改的是处理优先级,不是响应优先级。响应优先级焊在排队器的连线里,软件动不了;屏蔽字能做的是"我这段服务程序执行期间,允许谁打进来"。两者名字都带"优先级",管的却是不同时刻的不同事。
另有两个东西不属于这套体系,别往里塞。其一是 DMA 请求——它争的不是 CPU 的处理时间而是总线使用权,走的是总线仲裁,与中断判优是两套完全独立的机制(见 DMA 方式)。其二是子程序调用——中断由外部设备随机发起、时刻不可预知、与被打断的程序是平行关系,且需要判优电路等硬件支持;子程序由 CALL 发起、位置在编译时就确定、专为主程序服务、纯软件实现。两者都会"转去执行一段程序再回来",但发起方、可预知性、隶属关系三样全不同。
逐拍展开:三个响应条件、中断隐指令的三个动作、ISR 四大部分(想完整复述这条流程而不是只记结论时展开)
响应一个可屏蔽中断要同时满足三条:
| # | 条件 | 由什么表示 |
|---|---|---|
| 1 | 该中断源确实提出了请求且未被屏蔽 | 中断请求触发器 INTR |
| 2 | CPU 处于开中断状态 | 允许中断触发器 EINT |
| 3 | 一条指令执行完毕 | CPU 在每条指令执行阶段结束前才发出中断查询信号 |
第 3 条就是"设备发出请求后最多要等当前这条指令做完"的来历:指令执行到一半时,中间结果散落在 MDR 和各暂存器里,此刻打断根本无法准确保存现场。与之相对,异常由当前指令自身引发,在指令执行过程中就被检测到。
三条都满足后,由硬件自动完成三个动作,合称中断隐指令——它叫"指令",但指令系统里并没有这条指令,程序员也写不出它:
| 动作 | 为什么必须在这里做 |
|---|---|
| 关中断 | 保存断点这一步本身不能被新的中断打断,否则新断点会覆盖旧断点,原程序再也回不去 |
| 保存断点(PC、PSW) | 断点不保存就回不去;此刻软件尚未接管,这一步只能由硬件做 |
| 形成中断服务程序入口地址并送 PC | 交出控制权 |
入口地址具体怎么形成——中断类型号如何经数据线送回、向量地址与中断向量差在哪一层、向量中断与非向量中断的分别,见 异常和中断机制。
中断处理阶段的 ISR 分四大部分,不同设备的服务程序内容各异,但流程是同一个:
- 保护现场——把通用寄存器和状态寄存器的内容存到存储器或压入堆栈。断点已由中断隐指令存好,这里存的是其余寄存器。
- 中断服务——I/O 场景下就是从数据端口取走一个数据(或送出一个数据),必要时启动下一次传送。这是整段程序里唯一与"这台设备是什么"有关的部分。
- 恢复现场——用取数指令或 POP 把保存的内容送回原寄存器,顺序与保护时相反。
- 中断返回——最后一条指令是中断返回指令,从栈中取回 PC 与 PSW,回到断点。
单重与多重中断、中断屏蔽:为什么一切都取决于开中断放在哪一步(想弄清嵌套条件与两种优先级的分工时展开)
ISR 执行到一半时可能又有新的中断请求到来。按 CPU 理不理它分成两种,两者的服务程序流程只差一处:
| 含义 | ISR 里"开中断"的位置 | |
|---|---|---|
| 单重中断 | 执行 ISR 期间对新请求一律不理,做完再说 | 放在中断返回之前,整个服务过程全程关中断 |
| 多重中断(中断嵌套) | 允许处理优先级更高的中断打断当前 ISR,处理完再回来 | 提前到保护现场之后,此后就能被打进来 |
道理很直接:CPU 一旦响应中断,硬件已自动把 EINT 置 0(中断隐指令的第一步),此后若不执行开中断指令,任何新请求都进不来。开中断放得越早,能被打断的窗口越大。
多重中断里,恢复现场之前要再关一次中断——恢复现场同样是一段不能被打断的操作,理由与中断隐指令里关中断排第一完全相同。多重中断成立要两条:当前 ISR 里已经开中断(EINT
中断屏蔽是给"谁能打断谁"留的软件旋钮:每个中断源在接口里都有一个中断屏蔽触发器(MASK),MASK
从 I/O 的角度看,它解决的是一个很实际的问题:慢速设备的服务程序不该挡住快速设备。打印机的 ISR 可能要跑很久,如果它把磁盘的请求一直屏蔽着,磁盘就会丢数据;把磁盘的处理优先级调到打印机之上,磁盘就能在打印机的 ISR 执行途中打进来。这也正是两种优先级必须分开的原因:硬件排队器的次序是焊死的,而"谁更耽误不起"随设备配置而变。
四、什么时候中断方式根本不能用
把上一节那条流程整个走一遍是要花时间的,而设备不会等。中断方式成立因此有一个物理前提:
违反它的后果不是"性能差",而是丢数据。所以这类判断的起手式固定为算两个时间、比大小:
(每次传输字节数 ÷ 数据传输率) (单次中断周期数 ÷ 主频) - 前者
后者 → 中断方式可行;否则必须改用 DMA
两道量化演算:定时查询的占比、以及中断方式能不能成立(想核对自己会不会踩单位与位宽两个坑时展开)
(一)定时查询的 CPU 占比。 某机主频 800 MHz,采用定时查询方式,每次查询(读状态、判断、传送数据)共占 60 个时钟周期。外设数据传输率 200 KB/s,接口的数据缓冲寄存器为 16 位,要求不丢失任何数据。
数据缓冲寄存器 16 位,故每次传送
若误按
(二)中断方式能否成立。 某机主频 1 GHz,某外设数据传输率 2 MB/s,接口数据缓冲寄存器 32 位,一次中断的响应与处理共需 1500 个时钟周期。先比时间,再算占比。
① 设备准备一个数据的时间(
② 一次中断的总耗时:
③ 判定:
④ 占比:
成立不等于合适:CPU 有四分之三的时间在伺候这一台设备,只剩四分之一跑其他程序。再快一点(比如 3 MB/s)就会越过那条线开始丢数据,此时唯一的出路是 DMA。结论要写"会丢数据",只写"CPU 占用率太高"没有触及问题的性质。同一台设备改用 DMA 后的占比只有 0.0488%,对照见 DMA 方式。
考点速记
- 条件传送(程序查询)的根本缺陷是 CPU 与外设串行工作,忙等是空转而非停机,优化查询程序无法消除;独占查询占 CPU 100%,定时查询才有定量空间,且
由数据端口位宽决定、查询间隔问的是"最长"。 - 中断方式把"CPU 去问"换成"设备来报",外设与 CPU 变成并行工作——这是它的全部收益;它没有减少 I/O 的 CPU 开销(单次反而更贵),减少的是等待时间。
- 一次中断五阶段请求 → 判优 → 响应 → 服务 → 返回,软硬件分界画在响应与服务之间:断点由硬件(中断隐指令:关中断 → 保存断点 → 形成入口地址)保存,现场由软件(ISR)保存;单重与多重只差开中断指令的位置;中断方式成立的物理前提是
,违反就丢数据、必须改用 DMA。
这一节在真题里被考过的形式:
这是 co 全科考得最密的一节之一——近十五年几乎每年一道选择题,另有大题的分问。问法只有两类:算占比,或者挑出关于中断机制的错误叙述。
- 算 CPU 占比(定时查询)(2011-22、2018-43 第 1 问)。骨架永远是"每秒介入次数
单次周期数 主频"。2011-22 把两个因子直接给了(每秒至少查 200 次、每次至少 500 周期、主频 50 MHz), ,几乎是套公式。2018-43 第 1 问要自己把因子先算出来:设备 A 传输率 2 MBps、数据缓冲寄存器 32 位(即 B),故准备一个数据要 ,这就是"最多间隔 2 μs 查询一次";每秒查 次、单次 周期,占比 。⚠️ 这一问把本篇三个坑一次踩全: 取位宽而非 1 字节、间隔问的是"最多"、单次开销要先乘 CPI。 - 算 CPU 占比(中断)与判断中断方式能否成立(2014-22、2018-43 第 2 问)。2014-22 给的是"每 400 ns 发一次请求、每次响应和处理 100 ns",占比就是
;题面那句"中断响应所允许的最长延迟时间为 50 ns"是干扰条件——它约束的是响应够不够及时,不进占比的分子分母。2018-43 第 2 问则是本篇那条物理前提的直接应用:设备 B 传输率 40 MBps、 B,准备一个数据只要 ,而一次中断至少 , ,不能采用中断 I/O 方式,理由要写"会丢数据"——只写"CPU 占用率过高"没有答到性质上。 - 挑出关于中断 I/O 的错误叙述(2022-21、2024-21、2017-22、2018-22、2021-22、2025-22,六年六道)。这批题的错项高度集中在四处,逐条对照本篇即可:
- 把物理前提写反(2022-21 的 C:外设准备数据的时间应"小于"中断处理时间)。必须是大于,否则丢数据。
- 把两种优先级混为一谈(2024-21 的 A:中断屏蔽字用于确定中断"响应"优先级)。屏蔽字定的是处理优先级,响应优先级焊在硬件排队器里。
- 把单重中断的性质套到多重中断上(2017-22 的 B:中断处理期间 CPU 处于关中断状态)。多重中断在保护现场之后就开中断了,这正是它能嵌套的原因。
- 把响应的三个条件写漏或写错(2018-22、2021-22)。2018-22 的正确项 C 就是条件②"CPU 处于中断允许状态";三个错项分别踩了判优依据(按优先级不是按先后次序)、中断隐指令的边界(它不保存通用寄存器)、响应时机(要等当前指令执行完,不是"立即暂停")。2021-22 的错项 A 说"仅在用户态下 CPU 才能检测和响应中断"——内核态同样能响应,中断响应与 CPU 处于哪个状态无关。
- 另有一道判断哪个事件触发外部中断(2025-22)。答 DMA 传送结束——它由 DMA 控制器这个外部部件发出。其余三项都在 CPU 内部:总线事务结束不产生中断请求,页故障与断点指令属于异常(由当前指令自身引发),不是外部中断。判据是"这个请求是不是由 CPU 之外的部件发出的"。
复习优先级:这一节的分值密度在整个 I/O 章里最高,两类问法各占一半。算占比那半靠三个口径(
易错:把
默认成 1 字节。它由数据缓冲寄存器的位宽决定,算错会差整整 倍。
易错:把
写反。这个不等式违反的后果是丢数据,不是变慢。
易错:以为中断方式减少了 I/O 的 CPU 开销。单次中断比单次查询更贵,它省的是等待时间。
易错:认为中断屏蔽字能改响应优先级。它改的是处理优先级。
易错:以为中断处理期间一律关中断。那只对单重中断成立。
易错:把中断隐指令说成"保存现场"。它只存断点(PC、PSW),通用寄存器由 ISR 用软件保存。
教材出处
- 程序直接控制 I/O 方式:无条件传送与条件传送(程序查询方式)、条件传送接口的六步握手过程:袁春风《计算机组成与系统结构》第 3 版 §8.4.1,印刷页 p288~p289
- 定时查询与独占查询的定义、独占查询下 CPU 花费 100% 时间在 I/O 上:同书 §8.4.1,印刷页 p290
- 中断控制 I/O 的基本思想(启动外设后阻塞当前进程、调度另一进程执行,外设与 CPU 并行工作):同书 §8.4.2,印刷页 p292
- 高速外设中断请求频率高、响应与处理的额外开销大,因而不适合采用中断 I/O 方式:同书 §8.4.2,印刷页 p301
- CPU 响应中断的条件(EINT
)与响应时间(每条指令执行阶段的结束时刻)、设备就绪且未被屏蔽(MASK )时才置中断请求触发器 INTR:唐朔飞《计算机组成原理》第 3 版 §5.5,印刷页 p197 - 一次中断处理归纳为中断请求、中断判优、中断响应、中断服务、中断返回五个阶段;中断服务程序流程的四大部分与"保护现场:断点由中断隐指令完成,通用寄存器和状态寄存器由中断服务程序完成":同书 §5.5,印刷页 p198
- 中断嵌套(多重中断)与单重中断的定义、两者"区别在于开中断的设置时间不同"、响应中断后硬件自动关中断(EINT 置 0):同书 §5.5,印刷页 p199~p200
相关知识
I/O 系统概述|I/O 接口|DMA 方式|I/O 方式对比|异常和中断机制