I/O 操作举例
前面五节各讲了一块:硬件路径、控制方式、软件分层、设备命名、缓冲、分配、SPOOLing、驱动接口。这一节把它们串成一条完整的链。
串一遍的价值在于:本章的选择题几乎都是问”某一步归谁管”,而只要能在脑中跑通这条链,任何一步的归属都是当场可查的。
机制
一次读磁盘的完整过程
以用户程序执行一句”从文件读一块数据”为例。
① 用户层 I/O 软件接到调用,产生一个 I/O 请求,通过系统调用陷入内核。进程由用户态转入内核态。
② 设备独立性软件开始工作,它做四件事:检查这个用户有没有权限访问该设备;把逻辑设备名经逻辑设备表 LUT 映射到具体的物理设备,并取得其驱动程序入口地址;通过四张控制表完成设备、控制器、通道的分配——三者齐备才继续,任一忙则把进程挂到对应的等待队列;为本次传输分配缓冲区。
③ 设备驱动程序接过控制权,把”读第 100 个逻辑块”这个抽象要求翻译成”移动到第 5 柱面、1 号磁头、7 号扇区”这样的具体参数,检查参数合法性,然后把参数写进设备控制器的控制寄存器,启动设备。若采用 DMA 方式,此处还要设置 DMA 控制器的四类寄存器。
④ 进程阻塞。 驱动程序启动设备后返回,请求 I/O 的进程转入阻塞态,调度程序另选一个进程运行。CPU 不空等。
⑤ 设备与控制器工作。 磁盘寻道、旋转、读出数据,经控制器送入内存缓冲区(DMA 方式下不经过 CPU)。
⑥ 传输完成,设备发出中断请求。 CPU 响应中断——保存断点、切换到内核态、跳转到中断入口,这三步由硬件自动完成。
⑦ 中断处理程序执行:保存现场,做必要的善后(检查有无错误、更新控制表状态、释放设备/控制器/通道并唤醒各等待队列上的进程),把请求 I/O 的那个进程从阻塞态唤醒为就绪态,恢复现场后返回。
⑧ 该进程被调度后继续执行,数据已在缓冲区中,由设备独立性软件搬到用户区,系统调用返回。
这条链的三条对称性
串完之后,有三处对称值得单独记住,它们都是选择题的落点:
第一,去程与回程走的是不同的路。 去程是自上而下的调用(用户层 → 设备独立性软件 → 驱动程序),回程是自下而上的中断(设备 → 中断处理程序 → 唤醒进程)。这正是中断处理程序位于最底层的原因——它不在调用链上,而是硬件事件的入口。
第二,分配与回收严格成对。 第 ② 步分配了设备、控制器、通道和缓冲区,第 ⑦ 步必须全部释放并唤醒等待者。任何一处漏掉,对应的等待队列上的进程就会永远睡下去。
第三,进程状态的变化恰好卡在两端。 第 ④ 步由运行态转阻塞态,第 ⑦ 步由阻塞态转就绪态——中间的整个传输过程中,这个进程都不在 CPU 上,而 CPU 一直在执行别的进程。这就是引入中断和 DMA 的全部收益。
输出操作的差别
输出(写)的流程与输入大体对称,但有一处重要差别:
若目标是独占设备且系统采用 SPOOLing,第 ② 步就不会真的去分配那台设备,而是在输出井中分配一块磁盘空间、挂上一张请求表,然后立即返回。用户进程根本不会阻塞,真正的输出由后台的输出进程稍后完成。
这一处差别正是 SPOOLing 的全部价值所在:它把第 ④~⑦ 步的等待,从用户进程身上挪走了。
边界
每一步归哪一层
把上面八步与四层结构对照,就是本章选择题的标准答题表:
| 步骤 | 归哪一层 |
|---|---|
| 产生 I/O 请求、格式化数据 | 用户层 I/O 软件 |
| 权限检查 | 设备独立性软件 |
| 逻辑名 → 物理名映射 | 设备独立性软件 |
| 设备/控制器/通道分配 | 设备独立性软件 |
| 缓冲区分配与管理 | 设备独立性软件 |
| 抽象要求 → 具体要求 | 设备驱动程序 |
| 写控制寄存器、启动设备 | 设备驱动程序 |
| 保存断点、切换到内核态 | 硬件(中断隐指令) |
| 把数据从控制器读进内存 | 中断处理程序(中断驱动方式下) |
| 唤醒等待进程 | 中断处理程序 |
哪些步骤 CPU 必须参与
这是与 5.1.2 交叉的高频考点:
CPU 必须参与的:第 ①③ 步(发起请求、分配资源、启动设备)、第 ⑦⑧ 步(中断处理与善后)。这两段合起来就是 DMA 的”预处理”和”后处理”。
CPU 不参与的:第 ⑤ 步的数据传输——前提是采用 DMA 或通道方式。若采用中断驱动方式,数据仍由 CPU 一个字一个字搬;若采用程序直接控制方式,CPU 连等待期间都要忙等。
所以”CPU 参与到什么程度”完全取决于 I/O 控制方式,这是判断此类题目的唯一依据。
进程在哪些时刻不占用 CPU
第 ④ 步之后到第 ⑦ 步之前,请求 I/O 的进程处于阻塞态,不占用 CPU。
但这有一个前提:采用的是中断驱动、DMA 或通道方式。 程序直接控制方式下进程从不阻塞——它全程占着 CPU 轮询。
这条与”哪种 I/O 方式会导致进程阻塞”是同一道题的两种问法。
扩展:I/O 性能优化的四个方向
本小节是对全章的归纳,不对应教材的某个独立小节。 它的用处是:选择题问”某项技术解决了什么问题”时, 先判断它属于下面哪一条线,答案通常就定了。
把本章出现过的所有技术按”它到底省掉了什么”归类,恰好落在四条线上:
① 减少 I/O 次数——磁盘高速缓存、预读、延迟写、合并小 I/O。思路是:能不访问慢设备就不访问。
② 提高并行性——中断、DMA、多缓冲、异步 I/O。思路是:让 CPU 与设备、以及多台设备之间重叠工作。
③ 优化访问顺序——磁盘调度算法、连续布局、请求合并。思路是:减少机械移动的代价。
④ 减少 CPU 参与——DMA、通道、智能控制器。思路是:CPU 不再逐字节搬运,也不再逐步组织。
做题时先判断题干问的是哪一条线:“减少磁头移动”是第 ③ 条(磁盘调度);“用户提交打印后很快返回”是第 ② 条的一个特例(SPOOLing 把等待挪走了);而”提高整机资源利用率”哪一条都不是,那是多道程序设计——这正是 5.2.4 那道真题的陷阱所在。
对照速查
| 一次读磁盘的八步 | 谁在做 | 进程状态 |
|---|---|---|
| ① 产生 I/O 请求 | 用户层 → 陷入内核 | 运行态 |
| ② 权限、映射、分配、缓冲 | 设备独立性软件 | 运行态 |
| ③ 翻译参数、启动设备 | 设备驱动程序 | 运行态 |
| ④ 阻塞,CPU 转去执行别的进程 | 调度程序 | 转阻塞态 |
| ⑤ 设备传输数据 | 设备/控制器/DMA | 阻塞态 |
| ⑥ 发出中断,响应中断 | 硬件 | 阻塞态 |
| ⑦ 善后、释放资源、唤醒 | 中断处理程序 | 转就绪态 |
| ⑧ 数据搬到用户区,返回 | 设备独立性软件 | 运行态 |
| 三条对称性 | |
|---|---|
| 去程 vs 回程 | 调用自上而下,中断自下而上 |
| 分配 vs 回收 | 第 ② 步分配的,第 ⑦ 步必须全部释放并唤醒 |
| 状态变化 | 第 ④ 步入阻塞,第 ⑦ 步回就绪 |
考点
- 八步流程及每一步的归属层次(本章选择题的标准答题表)
- 调用自上而下、中断自下而上——中断处理程序不在调用链上
- 分配与回收严格成对,三个等待队列都要唤醒
- CPU 参与的是头尾两段(即 DMA 的预处理与后处理)
- 进程阻塞的前提是采用中断/DMA/通道方式,程序直接控制方式下不阻塞
- SPOOLing 下输出请求不会让用户进程阻塞
- I/O 优化的四条线:减少 I/O 次数 / 提高并行性 / 优化访问顺序 / 减少 CPU 参与
链接
- 🏠 返回总览:操作系统第 5 章:输入/输出管理总览
- ⬅️ 上一节:5.2.5 设备驱动程序接口
- ➡️ 下一节:5.3.1 磁盘
- 🔗 四层的判据,见 5.1.3 I/O 软件层次结构
- 📖 名词库:第 5 章名词库