OS-07 输入输出系统

一、I/O控制方式的演进

I/O控制方式经历了从CPU完全参与到几乎不需CPU参与的发展过程,每一种新方式都是为了解决前一种方式的性能瓶颈。

I/O控制方式演进 轮询 CPU 100% 参与 中断驱动 每字节一次中断 DMA 每块一次中断 通道 独立处理器 CPU参与度逐渐降低,I/O效率逐渐提高 →

1.1 轮询(程序直接控制)

这是最原始的I/O方式。CPU不断读取设备的状态寄存器,检查设备是否准备好了。如果没准备好,CPU就空转等待。

形象理解:就像你在水壶前一直盯着,问"水开了吗?""水开了吗?"——CPU什么其他事都不能做。

缺点:CPU利用率极低,因为CPU的速度远快于I/O设备。

1.2 中断驱动

CPU向设备发出I/O请求后,不再等待,而是继续执行其他程序。当设备完成操作时,通过中断信号通知CPU。

形象理解:把水壶放在炉子上,设个闹钟,然后去做其他事。闹钟响了再去关火。

优点:CPU可以在I/O等待期间执行其他程序,利用率大幅提高。

缺点:对于每个字节的传输都需要一次中断,大量中断导致CPU频繁切换。

1.3 DMA(直接内存访问)

DMA控制器是一个专门的硬件,它可以直接在设备和内存之间传输数据,不需要CPU逐一处理每个字节。CPU只需设置好传输参数(源地址、目标地址、数据长度),然后DMA控制器独立完成数据传输,完成后发一个中断通知CPU。

典型应用:磁盘读写。读取一个4KB的磁盘块,如果使用中断驱动,需要产生4096次中断;使用DMA只需要1次中断。

1.4 通道

通道是一种更高级的I/O控制方式,它实际上是一个专门处理I/O操作的处理器。通道有自己的指令集,可以执行"通道程序"来自主完成复杂的I/O操作序列。

二、I/O子系统层次结构

操作系统中的I/O系统采用分层设计,每一层屏蔽下层的细节,为上层提供抽象服务。

用户层软件:应用程序通过系统调用接口(如file.read()、socket.send())发起I/O请求。

设备独立性软件:这一层实现了设备无关性。应用程序使用逻辑设备名(如/dev/lp0)访问设备,由这一层映射为具体的物理设备。同时,这一层还负责设备命名、保护、缓冲和错误处理。

设备驱动程序:每个设备类型都有对应的驱动程序。驱动程序理解设备硬件的特定命令格式,将上层的通用I/O请求转换为设备能理解的命令序列。

中断处理程序:处理设备完成I/O后发起的中断,唤醒等待I/O完成的进程。

三、SPOOLing技术

SPOOLing(假脱机操作)是一种将独占设备虚拟化为共享设备的技术。最典型的应用是打印机共享。

在没有SPOOLing的情况下,打印机一次只能为一个进程服务。有了SPOOLing,情况就不同了:

SPOOLing系统的组成

  • 输入井输出井:磁盘上开辟的缓冲区域,用于暂存I/O数据
  • 输入进程输出进程:负责数据在缓冲区和设备之间的传输
  • 井管理程序:控制缓冲区资源的使用

工作流程:多个进程同时提交打印任务 → 每个任务被写入磁盘的输出井中排队 → 打印机空闲时从输出井取出任务依次打印。从进程的角度看,打印机"看起来"是同时可用的——每个进程都感觉自己独占打印机。

核心思想:用磁盘这个共享设备 + 缓冲技术,将独占设备改造成"虚拟共享设备"。