Skip to content

第七章 中断、设备与 I/O:连接外部世界


1. I/O 为什么难:速度差了百万倍

CPU 一纳秒能做几条指令,机械磁盘一次寻道要几毫秒——差了六个数量级。如果 CPU 傻等设备,等一次磁盘的工夫本可以执行几百万条指令。设备管理的一切设计,都是围绕"别让快的等慢的"展开的:中断让 CPU 不用守着设备,DMA 让 CPU 不用搬运数据,缓冲让快慢双方各干各的,SPOOLing 让独占设备排队虚拟化。本章按这条主线走完,最后把七章知识串成一次完整的 read 之旅。

2. 设备的分类

分类维度类型特征例子
数据组织块设备以固定大小块为单位传输,可寻址、可随机访问磁盘、SSD
数据组织字符设备以字符流为单位,不可寻址,来了就处理键盘、鼠标、串口、打印机
共享属性独占设备同一时间只能一个进程用打印机
共享属性共享设备可多进程交替使用磁盘
速度低速/中速/高速键盘每秒几字节,磁盘每秒数百 MB

块设备可寻址所以能"调度请求顺序"(上一章的磁盘调度),字符设备没有位置概念,谈不上调度顺序。

3. I/O 控制方式的演进:这条线是高频考点

四种方式是一条演进链,每一代都在回答"上一代把谁累着了"

3.1 程序轮询(程序直接控制)

CPU 发出 I/O 命令后,在循环里反复读设备状态寄存器:"好了吗?好了吗?"直到设备就绪才传数据。CPU 与设备只能串行工作,等待期间 CPU 完全浪费。唯一优点是简单,适合极简单的嵌入式场景。

3.2 中断驱动

CPU 发出命令后就去干别的活;设备准备好了,通过中断喊 CPU 回来处理。它解决了轮询"CPU 空等"的问题,CPU 与设备得以并行。但新问题是:每传一个字(或一个字符)就要中断一次,中断处理本身有保存现场、恢复现场的固定开销——高速设备每秒产生几十万次中断,CPU 光应付中断就饱和了。而且数据仍然要 CPU 亲手在设备与内存之间搬。

3.3 DMA 直接存储器访问

DMA 控制器(白话:一个专职搬运数据的小硬件)接管搬运:CPU 只需告诉它"从设备读多少数据、放到内存哪个位置",然后就彻底走开;DMA 控制器直接在设备与内存之间传输一整块数据,全部完成后才发一次中断报告。

它解决了中断驱动"每字一中断 + CPU 亲自搬运"两大痛点。代价是 DMA 与 CPU 会争用内存总线(周期窃取),但这远比让 CPU 搬划算。

3.4 通道

大型机场景下设备成百上千,每次 DMA 的启动、纠错、多块连续传输仍要 CPU 组织。通道是更进一步的"I/O 专用小处理机":它能执行自己的通道程序,一次被启动后可自主完成涉及多块、多设备的复杂 I/O 序列,完成后才中断 CPU。CPU 从"组织 I/O"中也解放了。

3.5 四种方式对照表

对比项程序轮询中断驱动DMA通道
CPU 是否空等是,全程陪跑
数据由谁搬运CPUCPUDMA 控制器通道
干预粒度每个字全程干预每个字中断一次中断一次组块/一批 I O 中断一次
CPU 与设备并行
额外硬件中断机构DMA 控制器通道处理机

一句话点透:演进方向就是 CPU 的干预粒度从"字"到"块"再到"一整批 I/O",一步步把 CPU 从 I/O 中解放出来

4. 中断处理的完整流程

第一章讲过中断是"操作系统的心跳",现在补全处理细节:

要点三条:其一,CPU 是在每条指令执行完的间隙检查中断,不会把一条指令拦腰截断(缺页那类指令内异常除外);其二,现场保存分两段——程序计数器等由硬件自动压栈,其余寄存器由处理程序软件保存;其三,中断可以嵌套,高优先级中断可以打断低优先级中断的处理。

5. 缓冲技术:为什么能提速

缓冲区是内存里开辟的中转站,作用是削平速度差、攒零为整、解耦快慢双方的节奏

5.1 单缓冲、双缓冲、缓冲池

单缓冲:设备先把数据放进缓冲区,CPU 再从缓冲区取走处理。设备写缓冲和 CPU 处理不能同时针对同一块进行,两者仍要互相等一等。

双缓冲:开两块,设备往 A 写时 CPU 处理 B,写满与处理完后交换角色。理想情况下设备和 CPU 都不停——流水线思想。

缓冲池:系统级的一组公共缓冲区,按"空闲队列、装满输入的队列、待输出的队列"组织,所有进程和设备共用,避免每个任务各自霸占一堆缓冲区。

方案效果适用
单缓冲有中转,但双方仍需交替等待要求最简单的场合
双缓冲生产与消费重叠进行,接近不停机输入输出速率与处理速率相近时
缓冲池全系统统筹,利用率最高多设备多进程的通用系统

经典计算题口径:设备把数据送入缓冲区耗时 T,CPU 把缓冲区数据传送到用户区耗时 M,CPU 处理耗时 C。单缓冲每块数据的平均耗时 = max(C, T) + M;双缓冲 ≈ max(C + M, T)。理解而非硬背:单缓冲下"送入下一块"与"处理上一块"可并行,但传送 M 卡在中间必须串行;双缓冲把 M 也叠进了并行流水。

5.2 一句话分工

缓冲解决"速度不匹配、突发流量",是空间换时间;中断解决"谁来通知";DMA 解决"谁来搬运"。三者常在同一条 I/O 路径上协同出现。

6. SPOOLing 假脱机:用共享设备虚拟独占设备

打印机是独占设备:一旦分给进程 A,A 打完之前 B 只能干等,哪怕 A 十分钟才凑一行。

SPOOLing(假脱机)的做法:没有进程能真正拿到打印机。进程"打印"时,系统只是把内容完整写到磁盘上的输出井里,并在打印队列挂一张单子,进程立刻继续干活;后台的输出进程再从队列里逐份取出、真正送打印机打印。

效果:在每个进程看来,自己"独占"了一台瞬间完成的虚拟打印机;物理打印机则按队列有条不紊。本质是用磁盘这个共享设备 + 排队,把独占设备改造成共享设备,既提高了打印机利用率,也消除了进程等待。名字的来历:"外围设备同时联机操作",模拟了早年脱机输入输出的效果,故称"假脱机"。

7. 设备驱动与设备独立性

设备独立性:应用程序使用统一的接口(如按文件方式 open/read/write)访问设备,不与具体物理设备绑定。程序里写"输出到打印设备",今天接 A 品牌打印机、明天换 B 品牌,程序无需改动。

实现靠分层:内核规定统一的接口规范,各厂商为自己的硬件编写设备驱动程序(把统一接口的命令翻译成该设备的专用寄存器操作)。逻辑设备名到物理设备的映射由系统的设备表完成。UNIX"一切皆文件"正是设备独立性的极致体现——设备被挂成 /dev 下的文件,读写设备就像读写文件。

8. 全专题贯通图:一次 read 的完整旅程

进程执行 read(fd, buf, 4096) 读文件,把七章的知识全部串起来:

看懂这张图,就看懂了操作系统的日常:虚拟化提供了进程和地址空间这套舞台,并发让等待者让出 CPU、完成者被唤醒,持久化把文件名一路翻译到磁盘块。三大主线在每一次普通的 read 里同时上演。

9. 本章要点回顾

主题必须记住的结论
设备分类块设备可寻址可随机访问;字符设备是流式不可寻址
演进主线轮询→中断→DMA→通道:CPU 干预粒度从字到块到批,逐步解放
轮询CPU 全程陪跑空等,与设备完全串行
中断驱动解决空等,但每字一中断且 CPU 仍亲自搬数据
DMA硬件搬运整块数据,一块一中断;与 CPU 争总线
通道能执行通道程序的 I/O 小处理机,一批 I/O 一中断
缓冲单缓冲 max(C,T)+M;双缓冲近似 max(C+M,T);缓冲池全局共用
SPOOLing磁盘输出井 + 排队,把独占打印机虚拟成人手一台的共享设备
设备独立性统一接口 + 驱动程序翻译,应用不绑定具体硬件

10. 做题提醒

  1. "DMA 每传送一个字节就向 CPU 发一次中断"是错的——那是中断驱动方式;DMA 是一块数据传完才中断一次。
  2. 中断驱动相比轮询的本质进步是 CPU 与设备可以并行工作,不是"传输速度变快"。
  3. 通道与 DMA 的区别:通道能执行自己的通道程序、可控制多台设备;DMA 只会按设定搬一块数据。
  4. SPOOLing 题目三件套:磁盘上的输入井输出井、内存缓冲、后台输入输出进程;它把独占设备改造成共享设备,而不是把共享设备改成独占。
  5. 缓冲区设在内存中,不是设备里的硬件寄存器;缓冲能缓解速度不匹配,但不能提高设备本身的物理速度。
  6. 单缓冲、双缓冲计算题先画时间重叠图,认清哪些阶段能并行、哪些必须串行,再套 max 公式。