IO管理:从轮询到通道

本篇对应王道第五章(原 17 IO管理概述 + 18 设备独立性软件合并)。主线一句话:想尽办法减少 CPU 对 IO 的干预——四种控制方式是这条主线的四步进化,缓冲区、SPOOLing 是配套工具。

一、I/O 设备与控制器

IO 管理是 OS 设计中最凌乱也最具挑战的部分——设备五花八门,很难有通用一致的设计。

设备分类(按不同维度)

维度 分类
信息交换单位 块设备(以块为单位,传输速率高、可寻址可随机读写,如磁盘)/ 字符设备(以字符为单位,速率低、不可寻址,常用中断 IO,如键盘、打印机)
传输速率 低速(键盘鼠标,几~几百 B/s)/ 中速(激光打印机)/ 高速(磁盘、光盘)
使用特性 存储设备 / 输入输出设备(输入、输出、交互式)
共享属性 独占设备(同一时刻只能一个进程用,如打印机)/ 共享设备(时间段内多进程分时访问,如磁盘)/ 虚拟设备(SPOOLing 把独占改造成共享)

设备控制器:CPU 与设备之间的中间人

**I/O 接口(设备控制器)**接收 CPU 命令、控制设备工作,把 CPU 从繁杂的设备控制事务中解脱出来。三部分组成:

image-f3f78d85
  1. 与 CPU 的接口:数据线(数据/控制/状态信息)、地址线(寄存器编号)、控制线(读写信号)
  2. 与设备的接口:一个控制器可连多个设备,每接口传数据、控制、状态三类信号
  3. I/O 逻辑:对 CPU 命令译码,控制所选设备

六大功能:接收识别命令、数据交换、报告设备状态、地址识别、数据缓冲、差错控制。

I/O 端口与编址

I/O 端口 = 控制器中可被 CPU 直接访问的寄存器:数据寄存器(缓存输入输出数据)、状态寄存器(设备状态供 CPU 读)、控制寄存器(CPU 写入启动命令)。

编址两种方式:

image-293d18cd
独立编址 统一编址(内存映射 I/O)
思想 IO 端口单独一个地址空间,用专用 I/O 指令访问 从主存地址空间分一段给端口,普通访存指令就能访问
优点 地址线少、译码简单、寻址快;专用指令程序清晰 无需专门指令、灵活;编址空间大;保护可由虚拟存储机制实现
缺点 指令少灵活性差;要两组读写控制信号 占用主存地址空间;地址线全部参译码,电路复杂、速度慢

二、四种 I/O 控制方式(核心)

贯穿始终的宗旨:尽量减少 CPU 对 I/O 控制的干预,把 CPU 从繁杂 IO 事务中解放出来

1. 程序直接控制(轮询)

CPU 发出 IO 指令后不断循环测试设备状态,直到数据就绪才取走。

image-0ec1ba86

简单易实现,但 CPU 绝大部分时间耗在循环测试上,CPU 与设备串行工作——根源是没有中断机构,设备无法主动报告"我好了"。

2. 中断驱动

设备准备好数据后主动中断 CPU:CPU 发出读命令后继续干别的;指令周期末尾检查中断信号,来了就保存现场、转中断处理程序、取走一个字,再恢复现场。

image-c12529e4

设备准备数据期间 CPU 和设备并行,利用率明显提升。但仍有两个问题:数据交换必须经过 CPU 寄存器;CPU 以字(节)为单位干预——对块设备 IO 极其低效。

3. DMA:数据不经过 CPU

设备和内存之间开辟直接数据通路。三个特点:

  1. 传送单位是数据块(不再是字)
  2. 数据直接在设备和内存间传送,不经过 CPU
  3. 仅在一个/多个数据块的开始和结束才需要 CPU 干预
image-108228ef

DMA 控制器四类寄存器:CR(命令/状态)、MAR(内存地址)、DR(数据)、DC(数据计数器)。工作流程:CPU 设置初值启动 DMA → DMA 控制器全权负责传送(每次一个字,不需 CPU)→ 整块传完发一个中断。

4. 通道:让"小型处理机"管 IO

通道是一种特殊的处理机,能执行一系列通道指令。CPU 只需发一条 IO 指令(指明通道程序在内存的位置和要访问的设备),通道自己执行通道程序完成任务后再中断 CPU。实现 CPU、通道、设备三者并行

与一般处理机的区别:指令类型单一、没有自己的内存(通道程序放主机内存,与 CPU 共享)。与 DMA 的区别:DMA 需 CPU 控制传输块大小和内存位置,通道这些信息自己控制;一个 DMA 控制器对应一台设备,一个通道可以控制多台设备

裁缝店比喻(一图流记住四种方式)

想象客户要做一批衣服(CPU 要数据,裁缝是设备):

方式 对应场景
程序轮询 裁缝没有客户联系方式,客户每隔一会儿跑去裁缝店看做好没有——浪费时间
中断驱动 裁缝有联系方式,每做完一件打一个电话让客户来拿——省了瞎逛,但一件一趟还是累
DMA 客户雇一位专属秘书,交代好衣服放哪(内存地址);裁缝直接联系秘书,秘书取回放好,每 100 件报告一次——大幅省时
通道 秘书权力更大:自己决定衣服存哪、何时报告(100 件还是 10000 件);且能同时对接多位裁缝——CPU、通道、多设备全并行

三、I/O 软件层次结构

image-65228dc9

从上到下四层,每层利用下层服务、屏蔽实现细节、向上提供服务;接口不变,改一层不影响别层;只有最低层涉及硬件

层次 职责
用户层软件 库函数(如 printf),通过系统调用获取 OS 服务
设备独立性软件 统一接口、设备命名/保护、分配与回收、逻辑设备名→物理设备名映射、缓冲管理、差错控制、统一逻辑块
设备驱动程序 与硬件直接相关:把抽象请求(read/write)转成设备命令发给控制器;每类设备一个驱动
中断处理程序 保存被中断进程环境、处理后恢复现场;与硬件紧密相关,放最底层并尽量屏蔽

一次 read 的完整旅程:用户调 read(用户层)→ 设备独立层解析统一命令 → 驱动层把 read 翻译成该设备特有的指令(磁盘和打印机行为不同)→ 中断处理程序接管执行 → 硬件控制器按命令操控设备完成。

应用程序 I/O 接口

  • 字符设备接口:get/put(顺序存取,缓冲区收发字符)、in-control 通用指令(参数对应各设备特定功能)、open/close 实现互斥共享
  • 块设备接口:磁盘二维结构(磁道号+扇区号)被隐藏成线性编号 0~n-1;抽象命令映射为低层操作;常配 DMA;内存映射接口把文件映射到内存读写
  • 网络设备接口套接字接口(socket),本地套接字连接远程套接字收发数据

阻塞 I/O 与非阻塞 I/O

  • 阻塞 I/O:进程发起 IO 后被移入阻塞队列干等,IO 完成才唤醒。奶茶店点单守着等——不知道啥时候做好,只能一直等。简单,适合并发小
  • 非阻塞 I/O:发起 IO 后不阻塞,但需不断轮询询问是否完成,等待期间能干别的。点完单顺便逛商场,隔一会儿来问一次。并发量大时合适,缺点是轮询占 CPU

四、高速缓存与缓冲区

缓冲区要解决什么

  1. 缓和 CPU 与 IO 设备速度不匹配的矛盾
  2. 减少中断频率,放宽中断响应时间限制
  3. 解决数据粒度不匹配(设备按字、进程按块)
  4. 提高 CPU 与设备的并行性

实现:硬件缓冲器太贵(只在关键部位用),一般用内存。共享资源 → 使用时必须互斥

单缓冲

一块缓冲区。设设备输入一块耗时 T、缓冲区传到工作区耗时 M、CPU 处理耗时 C,缓冲区必须冲满才能取

  • T 与 C 可并行(设备往缓冲区灌数据时,CPU 处理上一块已传出的数据)
  • 平均处理一块时间 = Max(C, T) + M

双缓冲

两块轮流用:设备灌缓冲区 1 的同时,CPU 取缓冲区 2 的数据。T、M、C 三者并行程度更高:

  • 平均处理一块时间 = Max(C + M, T)

⚠️ 通信细节:两台机器间单缓冲只能单向传输;要双向就得各自配两个缓冲区(一个发送一个接收)。

循环缓冲

速度相差太远时双缓冲也不够用——多个缓冲区链成循环队列,in 指针指向第一个可输入的空缓冲区,out 指向第一个可提取的满缓冲区,沿链循环移动。

缓冲池

区别于缓冲区(只是一块内存):缓冲池是管理机制——数据结构 + 操作函数 + 公用缓冲区,供多进程共享。三类队列:空缓冲队列、输入队列(装满输入数据)、输出队列(装满输出数据);四种工作缓冲区(hin 收容输入 / sin 提取输入 / hout 收容输出 / sout 提取输出)。

image-43f1da5e

四种工作方式:收容输入(空队首摘缓冲 → 装输入数据 → 挂输入队列尾)、提取输入(输入队列首取 → 提取数据 → 用完挂空队尾)、收容输出提取输出——对称的四步循环。

💡 循环缓冲和缓冲池只需定性理解机理;单缓冲双缓冲按 Max 公式模板分析,以不变应万变

高速缓存 vs 缓冲区(必考对比)

高速缓存 Cache 缓冲区 Buffer
存什么 数据的副本 传输中的数据
目的 访问副本比访问原始数据快 缓和速度差异、减少 IO 次数
典型 磁盘高速缓存(逻辑上属于磁盘、物理上驻留内存的盘块信息)、TLB IO 缓冲

磁盘高速缓存两种形式:内存中开辟固定大小缓存区;或把未利用的内存空间当缓冲池供请求分页和磁盘 IO 共享。

五、设备分配与回收

总原则:充分发挥设备使用效率(让设备忙起来)+ 避免分配不当造成死锁

四张表(体现从属关系)

系统中通道 → 控制器 → 设备层层挂接,数据结构要体现这种层级:

数量 内容
DCT 设备控制表 每设备一张 设备类型、标识符(物理名唯一)、状态(忙/闲)、指向 COCT 的指针、重复执行次数或时间、设备队列队首指针(等待该设备的 PCB 队列)
COCT 控制器控制表 每控制器一张 指向 CHCT 的指针
CHCT 通道控制表 每通道一张 与通道连接的控制器表首址(一个通道管多个控制器)
SDT 系统设备表 全系统一张 所有物理设备的表目(含 DCT 入口)

回收:进程释放设备且无其他进程请求 → 把 DCT 的设备状态改为空闲即可。

分配三步

以独占设备为例:① 按物理设备名查 SDT 找到 DCT → 看状态:忙则挂设备等待队列,闲则分配设备;② 按 DCT 找 COCT → 忙则挂控制器等待队列,闲则分配控制器;③ 按 COCT 找 CHCT → 忙则挂通道等待队列,闲则分配通道。设备、控制器、通道三者都分到,分配才算成功,才能启动传送。

分配要考虑的因素

  • 固有属性:独占设备(独占分配)、共享设备(同时分给多进程、调度访问次序)、虚拟设备(可共享)
  • 分配算法:FCFS(按请求顺序排队)或最高优先级优先(同优先级再按 FCFS)
  • 安全性安全分配——发 IO 请求就阻塞直到完成,不会再申请别的资源,安全但 CPU 与设备串行不安全分配——发完请求继续跑,可能同时操作多个设备、推进快,但可能死锁
  • 设备独立性:进程用逻辑设备名请求,不指定具体物理设备——好处:分配灵活(该类设备忙可换同类另一台)、易于 I/O 重定向(换设备不用改程序)

逻辑设备名 → 物理设备名靠逻辑设备表 LUT(逻辑设备名、物理设备名、驱动程序入口地址)映射。LUT 两种设置:全系统一张(单用户系统,逻辑名不能重)或每用户一张(多用户系统,不同用户可用相同逻辑名)。

image-c877a0bc

六、SPOOLing:把独占设备变成"共享"

假脱机技术:用程序模拟脱机输入输出的外围控制机,将独占设备改造成共享设备

组成:

image-fb049dd2
  • 输入井/输出井:磁盘上开辟的两个存储区域,模拟脱机的磁盘;输入井收容 IO 设备输入的数据,输出井收容用户程序的输出数据;每进程的输入/输出数据是一个文件,链成队列
  • 输入/输出缓冲区:内存中暂存(设备 → 输入井、输出井 → 设备)
  • 输入/输出进程:模拟外围控制机,搬运数据
  • 井管理程序:控制作业与磁盘井之间的信息交换

打印机例子:多个进程发打印请求,SPOOLing 系统都答应,但不立即真把打印机分给谁,而是:① 在磁盘缓冲区申请空闲盘块暂存打印数据;② 申请一张空白打印请求表挂到打印队列。进程立刻拿到"已打印"的感觉就去干别的了——真打印在打印机空闲且任务排到队首时才进行,用户不可见。每个进程都觉得自己独占了一台打印机

特点

  1. 提高 IO 速度——对低速设备的操作变成对磁盘缓冲区的存取
  2. 独占设备改造为共享设备——实际并未给任何进程分配设备
  3. 实现了虚拟设备功能

为什么说是空间换时间:空间开销显然(磁盘开井);省的时间在于——没有 SPOOLing 时 CPU 向打印机输出数据就得迁就打印机的慢速度,等打完才能干别的;有了 SPOOLing,CPU 把数据甩到磁盘输出井(快)就走人,打印排队的事假脱机进程管。向磁盘写数据比向打印机写快得多,时间就省出来了。

七、设备驱动程序接口

驱动程序 = IO 系统上层与设备控制器之间的通信程序:接收抽象 IO 请求(read/write)转成具体命令发给控制器,再把控制器的信号传回上层。功能:

  1. 把抽象要求转为具体要求(如盘块号 → 盘面号、磁道号、扇区号)
  2. 检查请求合法性、了解设备状态、传递参数、设置工作方式
  3. 发出 IO 命令:设备空闲立即启动;忙则把请求者 PCB 挂到设备队列
  4. 及时响应控制器发来的中断,按类型调用相应中断处理程序

与普通程序的不同:抽象与具体的双向转换、与 IO 控制方式(中断/DMA)紧密相关、不同类型设备配不同驱动、基本部分常固化在 ROM 中、允许同时多次调用执行

统一接口要求:每个驱动与 OS 之间有相同或相近的接口(好添加新驱动);抽象设备名转物理设备名找驱动入口;对设备保护,防止无权用户使用。

八、盲点总复习

  1. 四种 IO 方式的进化目标只有一句话:减少 CPU 干预——轮询全程盯 → 中断按字报 → DMA 按块报不经过 CPU → 通道自己跑程序管多设备
  2. 通道指令类型单一、没有自己的内存(与 CPU 共享主机内存);一个通道可控制多台设备
  3. 独立编址用专用 I/O 指令(要两组读写控制信号);统一编址占主存空间、译码复杂
  4. 单缓冲 Max(C,T)+M,双缓冲 Max(C+M,T);两机通信要双向必须各配两个缓冲区
  5. 磁盘高速缓存逻辑上属于磁盘、物理上在内存——不是 CPU 与内存之间那个 Cache
  6. 缓冲区是共享资源,使用必须互斥;缓冲池 = 缓冲区 + 管理机制,可多进程共享
  7. 设备分配顺序:设备 → 控制器 → 通道,三者都到手才算成功
  8. 安全分配方式(请求即阻塞)CPU 与设备串行;不安全分配方式推进快但可能死锁
  9. 设备独立性 = 用逻辑设备名,好处是灵活 + IO 重定向;映射靠 LUT,多用户系统每用户一张 LUT(逻辑名可重)
  10. SPOOLing 三大关键词:磁盘上的井、内存中的缓冲区、模拟外围控制机的输入输出进程;本质是以空间换时间实现虚拟设备
  11. 驱动程序固化在 ROM;一个驱动对应一类设备
  12. 字符设备不可寻址 → 顺序存取 + 中断方式;块设备可寻址 → 随机存取 + DMA

四大管理还剩最后一块拼图:磁盘调度 → 09-磁盘与固态硬盘

⬅️ 🏠 00-操作系统总览 ➡️ 09-磁盘与固态硬盘