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 参与

链接