「OS」IO管理
I/O 设备
可以将数据输入到计算机,或接收计算机输出数据的外部设备。
UNIX 系统将外部设备抽象为一种特殊的文件 ,用户可以使用与文件操作相同的方式对外部设备进行操作。
总线(Bus
)是接入 I/O 设备的主要方式
分类
按使用特性:人机交互类、存储类、网络通信类
按信息交换单位 :
- 块设备:数据传输单位为块,传输速率高,可寻址。如磁盘
- 字符设备:数据传输单位为字符,一般采用中断驱动。如鼠标键盘等。
I/O 控制器
CPU 通过一个电子部件——I/O 控制器来实现 CPU 对设备的控制。
功能
- 接受和识别 CPU 发出的指令。I/O 寄存器有相应的控制寄存器来存放命令和参数。
- 向 CPU 报告设备的状态。I/O 控制器有相应的状态寄存器记录 I/O 设备当前的状态。
- 数据交换。I/O 控制器中会设置相应的数据寄存器。输出时,数据寄存器用于暂存C PU发来的数据,之后再由控制器传送备。输入时,数据寄存器用于暂存设备发来的数据,之后C PU从数据寄存器中取走数据。
- 地址识别。类似于内存的地址,为了区分设备控制器中的各个寄存器,也需要给各个寄存器设置一个特定的“地址”。I/O控制器通过CPU提供的“地址”来判断CPU要读/写的是哪个寄存器
组成
- 一个 I/O 控制器可能对应多个设备
- 相应的,数据寄存器、控制寄存器、状态寄存器也会有多个。有的计算机在内存地址后继续编址,称为内存映像 I/O。有的采用 I/O 专用地址,即寄存器独立编址
内存映像 I/O 简化了指令,可以采用对内存进行操作的指令对控制器进行操作。而独立编址则需要设置专门的指令来实现。
I/O 控制方式
程序直接控制
读操作:
- CPU 向 I/O 控制器发出读指令,设备启动,状态寄存器设为 1(未就绪)
- CPU 轮询检查 I/O 控制器的状态
- 输入设备准备好数据后将数据传给控制器,报告自身状态
- 控制器将输入的数据放到数据寄存器当中,将状态改为 0(已就绪)
- CPU 发现设备已就绪,就将数据寄存器中的内容读入 CPU 的寄存器中,再将 CPU 寄存器中的内容放入内存。
数据传输单位:每次读写一个字
数据流向:
- 读:I/O 设备 -> CPU -> 内存
- 写:内存 -> CPU -> I/O 设备
缺点:
- CPU 长期处于”忙等”状态,利用率低
中断驱动
在CPU发出读/写命令后,将等待 I/O 的进程阻塞,切换到别的进程执行。当 I/O 完成后,控制器会向CPU发出一个中断信号,CPU检测到中断信号后,会保存当前进程的运行环境信息,转去执行中断处理程序处理该中断。处理中断的过程中,CPU从 I/O 控制器读一个字的数据传送到CPU寄存器,再写入主存。接着,CPU恢复等待I/O的进程(或其他进程)的运行环境,然后继续执行。
- CPU会在每个指令周期的末尾检查中断;
- 如果中断发生的频率太高,也会降低系统性能。
DMA
DMA方式(Direct Memory Access,直接存储器存取。主要用于块设备的 I/O 控制),由一个专门的控制器来完成数据从内存到设备或者是从设备到内存的传输工作。
- 数据的传送单位是“块”。
- 数据的流向是从设备直接放入内存,或者从内存直接到设备。不再需要CPU作为中转。
- 仅在传送一个或多个数据块的开始和结束时,才需要CPU干预。
- DR (Data Register,数据寄存器):暂存从设备到内存,或从内存到设备的数据。
- MAR (Memory Address Register,内存地址寄存器):在输入时,MAR表示数据应放到内存中的什么位置;输出时MAR表示要输出的数据放在内存中的什么位置。
- DC(Data Counter,数据计数器):表示剩余要读/写的字节数。
- CR(Command Register,命令/状态寄存器):用于存放CPU发来的I/O命令,或设备的状态信息。
首先,CPU指明此次要进行的操作,并说明要读入多少数据、数据要存放在内存的什么位置、数据在外部设备上的地址(如:在磁盘上的地址)
控制器会根据CPU提出的要求完成数据的读/写工作,整块数据的传输完成后,才向CPU发出中断信号
CPU干预的频率:
- 仅在传送一个或多个数据块的开始和结束时,才需要CPU干预。
数据传送的单位:
- 每次读/写一个或多个块(注意:每次读写的只能是连续的多个块,且这些块读入内存后在内存中也必须是连续的)
数据的流向(不再需要经过CPU)
- 读操作(数据输入):I/O设备→内存
- 写操作(数据输出):内存→ I/O设备
缺点:CPU每发出一条 I/O 指令,只能读/写一个或多个连续的数据块。如果要读/写多个离散存储的数据块,或者要将数据分别写到不同的内存区域时,CPU要分别发出多条 I/O 指令,进行多次中断处理才能完成。
通道控制方式
通道:一种硬件,可以识别并执行一系列通道指令
流程:
- CPU向通道发出I/O指令。指明通道程序在内存中的位置,并指明要操作的是哪个 I/O 设备。之后CPU就切换到其他进程执行了
- 通道执行内存中的通道程序(其中指明了要读入/写出多少数据,读/写的数据应放在内存的什么位置等信息)
- 通道执行完规定的任务后,向CPU发出中断信号,之后CPU对中断进行处理
CPU干预的频率:极低,通道会根据CPU的指示执行相应的通道程序,只有完成一组数据块的读/写后才需要发出中断信号,请求CPU干预。
数据传送的单位:每次读/写一组数据块
缺点:实现复杂,需要专门的通道硬件支持
优点:CPU、通道、I/O 设备可并行工作,资源利用率很高。
I/O 软件层次结构
- 用户层软件:用户可直接使用该层提供的与 I/O 操作相关的库函数(Windows API)对设备进行操作;同时通过“系统调用”请求操作系统内核的服务
- 设备独立性软件:与设备硬件特性无关的功能基本均在这一层实现
- 向上层提供统一的调用接口
- 设备保护。原理类似文件保护,不同用户对设备的访问权限也不同
- 差错处理。对一些设备的错误进行的处理。
- 设备的分配与回收。
- 数据缓冲区管理。通过缓冲技术屏蔽设备之间数据交换单位大小和传输速度的差异
- 建立逻辑设备名到物理设备名的映射,根据设备类型选择调用相的驱动程序。这是根据逻辑设备表(LUT)来实现的。
操作系统系统可以采用两种方式管理逻辑设备表(LUT):第一种:整个系统只设置一张LUT,这就意味着所有用户不能使用相同的逻辑设备名,因此这种方式只适用于单用户操作系统。第二种:为每个用户设置一张LUT,各个用户使用的逻辑设备名可以重复,适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程,而LUT就存放在用户管理进程的PCB中。
- 设备驱动程序:主要负责对硬件设备的具体控制,将上层命令转化为特定设备可执行的一系列操作,如设置设备寄存器、检查设备状态等。
由于不同的 I/O 设备往往有不同的硬件特性 ,因此厂家需要根据设备的硬件特性设计并提供相应的驱动程序 - 中断处理程序:进行中断处理
- 硬件
设备独立性:
应用程序独立于具体使用的物理设备。为了实现设备独立性而引入了逻辑设备和物理设备这两个概念。在应用程序中, 使用逻辑设备名称来请求使用某类设备;而系统在实际执行时, 还必须使用物理设备名称。因此,系统须具有将逻辑设备名称转换为某物理设备名称的功能。
I/O 核心子系统
I/O调度
磁盘调度:(先来先服务算法、最短寻道优先算法、SCAN算法、C-SCAN算法、LOOK算法、C-LOOK算法)。当多个磁盘 I/O请求到来时,用某种调度算法确定满足 I/O 请求的顺序。
设备保护
每个设备也有对应的 FCB,当用户请求访问某个设备时,系统根据 FCB 中记录的信息来判断该用户是否有相应的访问权限,从而实现”设备保护”
假脱机技术(SPOOLing)
脱机技术:
脱机技术指的是脱离主机的控制进行输入输出操作。很久以前是纸带输入,速度太慢,于是通过外围控制机将纸带数据输入到磁带,再输入主机,输出同理。
作用:缓解CPU与慢速I/O设备的速度矛盾,实现预输入、缓输出。
假脱机技术:利用软件的方式模拟脱机技术。可以把一台物理设备虚拟成逻辑上的多台设备。
技术原理
输入井和输出井:模拟脱机输入/输出时的磁带
输入进程和输出进程:模拟脱机输入/输出时的外围控制机
共享打印机原理
虽然系统中只有一台打印机,但每个进程提出打印请求时,系统都会为在输出井中为其分配一个存储区(相当于分配了一个逻辑设备),使每个用户进程都觉得自己在独占一台打印机,从而实现对打印机的共享。
设别的分配与回收
设备分配时应考虑的因素有:
- 设备的固有属性
- 独占设备:一个时间段只能分配给一个进程(如打印机)
- 共享设备:可同时分配给多个进程(如磁盘),但各进程往往是宏观上同时共享使用设备,而微观上交替使用
- 虚拟设备:采用 SPOOLing 技术将独占设备改造成虚拟的共享设备
- 设备分配算法
- 设备分配中的安全性
- 安全分配方式:为进程分配一个设备后就将进程阻塞, I/O 完成再唤醒。一个时段内每个进程只能使用一个设备
优点:破坏了“请求和保持”条件,不会死锁
缺点:对于一个进程来说,CPU和 I/O 设备只能串行工作 - 不安全分配方式:进程请求I/O,操作系统负责分配设备,进程可以继续执行或者请求新的I/O,直到某个I/O无法满足才阻塞进程。
优点:进程的计算任务和 I/O 任务可以并行处理,使进程迅速推进
缺点:有可能发生死锁
- 安全分配方式:为进程分配一个设备后就将进程阻塞, I/O 完成再唤醒。一个时段内每个进程只能使用一个设备
静态分配和动态分配
静态分配:进程运行前为其分配全部所需资源,结束后归还。(破坏”请求和保持”条件,不会死锁)
动态分配:进程运行过程中动态申请设备资源
数据结构
一个通道控制多个设备控制器,一个设备控制器控制多个设备。
因此系统为每个设备配置一张设备控制表(DCT)用于记录设备情况
每个设备控制器都会对应一张控制器控制表(COCT)。
每个通道对应一张通道控制表(CHCT)。
系统中还有系统设备表(SDT),记录了系统中全部设备的情况。
分配过程:
注:只有设备、控制器、通道三者都分配成功,此次设备分配才算成功,之后便可启动 I/O 设备进行数据传送
分配过程改进:
逻辑设备表(LUT)建立了逻辑设备名与物理设备名之间的映射关系。
某用户进程第一次使用设备时使用逻辑设备名向操作系统发出请求,操作系统根据用户进程指定的设备类型(逻辑设备名)查找系统设备表,找到一个空闲设备分配给进程,并在LUT中增加相应表项。
如果之后用户进程再次通过相同的逻辑设备名请求使用设备,则操作系统通过LUT表即可知道用户进程实际要使用的是哪个物理设备了,并且也能知道该设备的驱动程序入口地址。
逻辑设备表的设置问题:
- 整个系统只有一张LUT:各用户所用的逻辑设备名不允许重复,适用于单用户操作系统
- 每个用户一张LUT:不同用户的逻辑设备名可重复,适用于多用户操作系统
缓冲区管理
缓冲区是一个存储区域, 可以使用专门的硬件寄存器实现,成本高容量小(如 TLB)
更多时候使用内存做缓冲区
作用:
- 缓和CPU与I/O的速度矛盾
- 减少对CPU的中断频率,放宽对CPU中断的时间限制(中断驱动的字符型设备)
- 解决数据粒度不匹配的问题(输出进程每次生成一块数据,但 I/O 设备每次只能输出一个字符)
- 提高CPU与I/O的并行性
单缓冲
假设某用户进程请求某种块设备读入若干块的数据。若采用单缓冲的策略,操作系统会在主存中为其分配一个缓冲区(若题目中没有特别说明,一个缓冲区的大小就是一个块)。
注意:当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出;当缓冲区为空时,可以往缓冲区冲入数据,但必须把缓冲区充满以后,才能从缓冲区把数据传出。
双缓冲
顾名思义,在主存分配两个缓冲区。
管道通信中的”管道”就是缓冲区。因此要实现数据双向传输,就必须设置两个管道
循环缓冲区
将多个大小相等的缓冲区链接成一个循环队列。
缓冲池
缓冲池由系统中共用的缓冲区组成。这些缓冲区按使用状况可以分为:空缓冲队列、装满输入数据的缓冲队列(输入队列)、装满输出数据的缓冲队列(输出队列)。
另外,根据一个缓冲区在实际运算中扮演的功能不同,又设置了四种工作缓冲区:用于收容输入数据的工作缓冲区(hin)、用于提取输入数据的工作缓冲区(sin)、用于收容输出数据的工作缓冲区(hout)、用于提取输出数据的工作缓冲区(sout)