25输入输出管理
I/O设备基本概念
I/O"就是"输入/输出",Input/Output
I/O 设备:
- 可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备,属于计算机中的硬件部件
- 输入设备如鼠标、键盘;输出设备如显示器;既可输入又可输出设备如硬盘
UNIX系统将外部设备抽象为一种特殊的文件,用户可以使用与文件操作相同的方式对外部设备进行操作
- Write操作:向外部设备写出数据
- Read操作:从外部设备读入数据
I/O设备按照使用特性分类:
- 人机交互类外部设备:
- 用于人机交互的外部设备,如鼠标、键盘、打印机等
- 该类设备数据传输速度慢
- 存储设备:
- 用于数据存储的外部设备,如移动硬盘、光盘等
- 数据传输速度快
- 网络通信设备:
- 用于网络通信的外部设备,如调制解调器等
- 数据传输速度介于人机交互类设备于存储设备之间
I/O设备按照传输速度分类:
- 低速设备:
- 传输速率为每秒几个到几百字节,如鼠标、键盘等
- 中速设备:
- 传输速率为每秒数千至上万个字节,如激光打印机等
- 高速设备
- 传输速率为每秒数千字节至千兆字节的设备,如磁盘等
I/O设备按照信息交换的单位分类:
- 块设备:
- 数据传输的基本单位是"块",如磁盘等
- 传输速率较高,可寻址,即对该设备可随机地读/写任意一个块
- 字符设备:
- 数据传输的基本单位是字符,如鼠标、键盘等
- 传输速率较慢,不可寻址,在输入/输出时常采用中断驱动方式(I/O控制方式)
I/O控制器
I/O设备有机械部件和电子部件组成
- 机械部件:
- 主要用于执行具体的I/O操作
- 如鼠标/键盘的按钮;显示器的LED屏;移动硬盘的磁臂、磁盘盘面
- 电子部件:
- 通常是一块插入主板扩充槽的印刷电路板
- CPU无法直接控制I/O设备的机械部件,因此I/O设备还要有一个电子部件作为CPU和I/O设备机械部件之间的"中介",用于实现CPU对设备的控制
- 该电子部件就是I/O控制器,又称设备控制器
- CPU可控制I/O控制器,又由I/O控制器来控制设备的机械部件
I/O控制器的功能:
- 接收和识别CPU发出的命令:
- 如CPU发来的read/write 命令,I/O控制器中会有相应的控制寄存器来存放命令和参数
- 向CPU报告设备的状态:
- I/O控制器中会有相应的状态寄存器,用于记录I/O设备的当前状态
- 如:1表示空闲,0表示忙碌
- 数据交换:
- I/O控制器中会设置相应的数据寄存器
- 输出时,数据寄存器用于暂存CPU发来的数据,之后再由控制器传送设备
- 输入时,数据寄存器用于暂存设备发来的数据,之后CPU从数据寄存器中取走数据
- 地址识别:
- 类似于内存的地址,为了区分设备控制器中的各个寄存器,也需要给各个寄存器设置一个特定的"地址"
- I/O控制器通过CPU提供的"地址"来判断CPU要读/写的是哪个寄存器
I/O控制器组成

- 一个I/O控制器可能会对应多个设备
- 数据寄存器、控制寄存器、状态寄存器可能有多个(如:每个控制/状态寄存器对应一个具体的设备),且这些寄存器都要有相应的地址,才能方便CPU操作。有的计算机会让这些寄存器占
用内存地址的一部分,称为内存映像I/O;另一些计算机则采用I/O专用地址,即寄存器独立编址
CPU于I/O控制交互过程:
- CPU与I/O控制器的I/O逻辑模块进行数据交换,通过控制线告知进行什么I/O指令/命令,通过地址线告知需要对哪个I/O接口/设备进行操作
- 同时,CPU会通过数据总线将需要输出的数据传给I/O控制器的数据寄存器,从而让I/O逻辑模块可以从I/O控制器的数据寄存器中获取到需要输出的数据
- CPU在执行某些I/O指令可能会附带一些参数,这些参数也会通过数据总线传入I/O控制器的控制寄存器
- 在进行I/O处理过程中,I/O设备出现的故障以及运行状态会从I/O接口中传给I/O逻辑模块,I/O逻辑模块又会将这些状态信息传入I/O控制器的状态寄存器,CPU会通过数据总线将状态寄存器的数据读入,以获取I/O设备的运行状态
I/O控制器中寄存器的编制方式:

- 内存映射I/O:
- 控制器中的寄存器与内存地址统一编址
- 优点:
- 简化了指令。可以采用对内存进行操作的指令来对控制器进行操作
- 寄存器独立编址:
- 控制器中的寄存器使用单独的地址
- 有些计算机可能每个设备控制器的寄存器都从0开始编号;另外一些计算机可能将所有寄存器整体进行编号
- 缺点:
- 要设置专门的指令来实现对控制器的操作,不仅要指明寄存器的地址,还要指明控制器的编号
- 控制器中的寄存器使用单独的地址
I/O控制方式
I/O控制方式:控制I/O设备的数据读/写的方式
| 控制方式 | 完成一次读/写过程 | CPU干预频率 | 每次I/O数据传输单位 | 数据流向 |
|---|---|---|---|---|
| 程序直接控制方式 | CPU发出I/O命令后需要不断轮询 | 极高 | 字 | 设备 -> CPU -> 内存 内存 -> CPU -> 设备 |
| 中断驱动方式 | CPU发出I/O命令后可以做其他事,本次I/O完成后设备控制器发出中断信号 | 高 | 字 | 设备 -> CPU -> 内存 内存 -> CPU -> 设备 |
| DMA方式 | CPU发出I/O命令后可以做其他事,本次I/O完成后DMA控制器发出中断信号 | 中 | 块 | 设备 -> 内存 内存 -> 设备 |
| 通道控制方式 | CPU发出I/O命令后可以做其他事。通道会执行通道程序以完成I/O,完成后通道向CPU发出中断信号 | 低 | 一组块 | 设备 -> 内存 内存 -> 设备 |
从程序直接控制方式 - 中断驱动方式 - DMA方式 - 通道控制方式的发展过程看,逐步减少了CPU对I/O过程的干预,解放CPU去完成其他任务,从而提高效率
程序直接控制方式
最早期的I/O控制方式,特点是轮询
完成一次读/写操作的流程:(读操作)
- CPU通过控制线向I/O控制器发出读指令,I/O逻辑部件控制设备启动,并且状态寄存器设为1
- 轮询检查控制器状态
- 其实CPU在不断地执行轮询检查,若状态位一直是1,说明设备还没准备好要输入的数据,直至读出状态位更新
- 输入设备准备好数据后通过I/O设别接口将数据传给I/O控制器,并报告自身状态
- I/O控制器I/O逻辑部件将来自I/O设备输入的数据放入内部数据寄存器中,并将状态改为0,表示已就绪
- CPU发现设备已就绪,即可将I/O控制器内部数据寄存器中的内容读入CPU的寄存器中,再把CPU寄存器中的内容放入内存
- 如果还要继续读入数据,则CPU继续发出读指令
流程图

- CPU从控制器中读出字后,输入的数据最终是要放在内存存储器中的
- 同理,输出的数据也要放在内存中,从内存取出传给控制器用于打印
CPU干预的频率:
- 很频繁,I/O操作开始之前、完成之后需要CPU介入,并且在等待I/O完成的过程中CPU需要不断地轮询检查
数据传送的单位:每次读写一个字
数据的流线:
- 读操作(数据输入):I/O设备 -> CPU -> 内存
- 写操作(数据输出):内存 -> CPU -> I/O设备
- 每个字的读/写都需要CPU的帮助
程序直接控制方式特点:
- 优点:
- 实现简单,在读/写指令之后,加上实现循环检查的一系列指令即可(因此才称为"程序直接控制方式")
- 缺点:
- CPU和I/O设备只能串行工作,CPU需要一直轮询检查,长期处于"忙等"状态,CPU利用率低
中断驱动方式
I/O控制直接使用中断实现
- 由于I/O设备速度很慢,因此在CPU发出读/写命令后,可将等待I/O的进程阻塞,先切换到别的进程执行
- 当I/O完成后,控制器会向CPU发出一个中断信号,CPU检测到中断信号后,会保存当前进程的运行环境信息,转去执行中断处理程序处理该中断
- 处理中断的过程中,CPU从I/O控制器读一个字的数据传送到CPU寄存器,再写入主存
- 接着,CPU恢复等待I/O的进程(或其他进程)的运行环境,然后继续执行
完成一次读/写操作的流程图:(读操作)

CPU干预的频率:
- 每次I/O操作开始之前、完成之后需要CPU介入
- CPU接收到I/O请求
- 等待I/O完成的过程中CPU可以切换到别的进程执行
数据传送的单位:每次读写一个字
数据的流线:
- 读操作(数据输入):I/O设备 -> CPU -> 内存
- 写操作(数据输出):内存 -> CPU -> I/O设备
中断驱动控制方式特点:
- 优点:
- 与"程序直接控制方式"相比,在"中断驱动方式"中,I/O控制器会通过中断信号主动报告I/O已完成,CPU不再需要不停地轮询
- CPU和I/O设备可并行工作,CPU利用率得到明显提升
- 缺点:
- 每个字在I/O设备与内存之间的传输,都需要经过CPU,而频繁的中断处理会消耗较多的CPU时间
DMA方式
与"中断驱动方式"相比,DMA方式Direct Memory Access,直接存储器存取:
- 数据的传送单位是"块"。不再是一个字、一个字的传送
- 数据的流向是从设备直接放入内存,或者从内存直接到设备。不再需要CPU作为"快递小哥"
- 仅在传送一个或多个数据块的开始和结束时,才需要CPU干预
完成一次读/写操作的流程:

DMA控制器组成:

- 数据寄存器DR,Data Register:
- 暂存从设备到内存,或从内存到设备的数据
- 内存地址寄存器MAR,Memory Address Register:
- 在输入时,MAR 表示数据应放到内存中的什么位置
- 输出时MAR 表示要输出的数据放在内存中的什么位置
- 数据计数器DC,Data Counter:
- 表示剩余要读/写的字节数
- 命令/状态寄存器CR,Command Register:
- 用于存放CPU发来的I/O命令,或设备的状态信息
CPU干预的频率:
- 仅在传送一个或多个数据块的开始和结束时,才需要CPU干预
数据传送的单位:
- 每次读/写一个或多个块
- 每次读写的只能是连续的多个块,且这些块读入内存后在内存中也必须是连续的
数据的流线:
- 读操作(数据输入):I/O设备 -> 内存
- 写操作(数据输出):内存 -> I/O设备
DMA方式特点:
- 优点:
- 数据传输以"块"为单位,CPU介入频率进一步降低。数据的传输不再需要先经过CPU再写入内存,数据传输效率进一步增加。CPU和I/O设备的并行性得到提升
- 缺点:
- CPU每发出一条I/O指令,只能读/写一个或多个连续的数据块。
- 如果要读/写多个离散存储的数据块,或者要将数据分别写到不同的内存区域时,CPU要分别发出多条I/O指令,进行多次中断处理才能完成
通道控制方式
该种控制方式采用通道实现
通道:
- 一种硬件,可以理解为是"弱鸡版的CPU"
- 通道可以识别并执行一系列通道指令
- 与CPU相比,通道可以执行的指令很单一,并且通道程序是放在主机内存中的,也就是说通道与CPU共享内存
完成一次读/写操作的流程:(读操作)

- CPU向通道硬件发出I/O指令,指明通道程序或当前通道指令在内存中的位置,并指明要操作的是哪个I/O设备。随后就CPU就切换到其他进程执行
- 通道执行内存中的通道程序
- 通道程序相当于是一系列通道指令的集合
- 其中指明了要读入/写出多少数据,读/写的数据应放在内存的什么位置等信息
- 通道执行完规定的任务后,向CPU发出中断信号,之后CPU对中断进行处理
CPU干预的频率:
- 极低,通道会根据CPU的指示执行相应的通道程序,只有完成一组数据块的读/写后才需要发出中断信号,请求CPU干预
数据传送的单位:
- 每次读/写一组数据块
数据的流线:(在通道的控制下进行)
- 读操作(数据输入):I/O设备 -> 内存
- 写操作(数据输出):内存 -> I/O设备
通道控制方式特点:
- 优点:
- 实现复杂,需要专门的通道硬件支持
- 缺点:
- CPU、通道、I/O设备可并行工作,资源利用率很高
I/O软件层次结构

- 越上面的层次越接近用户;越下面的层次越接近硬件
- 每一层会利用其下层提供的服务,实现某些功能,并屏蔽实现的具体细节,向高层提供服务("封装思想")
硬件层直接执行I/O操作,由机械部件、电子部件组成
- 直接涉及到硬件具体细节、且与中断无关的操作肯定是在设备驱动程序层完成的;
- 没有涉及硬件的、对各种设备都需要进行的管理工作都是在设备独立性软件层完成的
用户层软件
用户层软件:
- 也叫系统调用处理层,实现了与用户交互的接口,用户可以直接使用该层提供的、与I/O操作相关的库函数对设备进行操作
- 用户层软件将用户请求翻译成格式化的I/O请求,并通过系统调用请求操作系统内核的服务
如,printf("hello world!");会被翻译成等价的write系统调用,用户曾软件也会在系统调用是填入相应的参数
Windows操作系统向外提供一系列系统调用
- 由于系统调用的格式严格,使用麻烦
- 用户层上封装了一些列更方便的库函数接口,供用户使用,即Windows API
设备独立性软件
设备独立性软件:
- 又称设备无关性软件,与设备的硬件特性无关的功能几乎都在这一层实现
- 设别独立性软件就是软件层使用的系统调用
设备独立性软件主要实现的功能:
- 向上层提供统一的调用接口,如read/write 系统调用
- 设备的保护,原理类似与文件保护
- 设备被看做是一种特殊的文件,不同用户对各个文件的访问权限是不一样的,同理,对设备的访问权限也不一样
- 差错处理
- 设备独立性软件需要对一些设备的错误进行处理
- 设备的分配与回收
- 设备也属于一种临界资源,需要解决进行互斥、同步问题,该层软件实现了这方面的功能
- 数据缓冲区管理
- 可以通过缓冲技术屏蔽设备之间数据交换单位大小和传输速度的差异
- 建立逻辑设备名到物理设备名的映射关系;根据设备类型选择调用相应的驱动程序
逻辑设备
用户或用户层软件发出I/O操作相关系统调用的系统调用时,需要指明此次要操作的I/O设备的逻辑设备名
- 如,去学校打印店打印时,需要选择打印机1/打印机2/打印机3 ,其实这些都是逻辑设备名
设备独立性软件通过逻辑设备表LUT,Logical Unit Table,来确定逻辑设备对应的物理设备,并找到该设备的对应的设备驱动程序
| 逻辑设备名 | 物理设备名 | 驱动程序入口地址 |
|---|---|---|
| /dev/打印机1 | 3 | 1024 |
| /dev/打印机2 | 5 | 2046 |
| ... | ... | ... |
- 操作系统系统可以采用两种方式管理逻辑设备表LUT:
- 整个系统只设置一张LUT,这就意味着所有用户不能使用相同的逻辑设备名
- 只适用于单用户操作系统
- 为每个用户设置一张LUT,各个用户使用的逻辑设备名可以重复
- 适用于多用户操作系统
- 系统会在用户登录时为其建立一个用户管理进程,而LUT就存放在用户管理进程的PCB中
- 这两种方式类比于目录结构中的单级目录和二级目录
- 整个系统只设置一张LUT,这就意味着所有用户不能使用相同的逻辑设备名
- I/O设备被当做一种特殊的文件,不同类型的I/O设备需要有不同的驱动程序处理
设备驱动程序
各式各样的设备,外形不同,其内部的电子部件(I/O控制器)也有可能不同
- 不同打印机,其控制器内的数据寄存器设计的数量可能不同,其状态寄存器中表示设备状态的状态码也可能不同
不同设备的内部硬件特性也不同,这些特性只有厂家才知道
- 厂家须提供与设备相对应的驱动程序,CPU执行驱动程序的指令序列,来完成设置设备寄存器,检查设备状态等工作
设备驱动程序主要负责对硬件设备的具体控制
- 将上层发出的一系列命令(如read/write)转化成特定设备"能听得懂"的一系列操作
- 包括设置设备寄存器;检查设备状态等
- 设备独立性软件及上层软件并不对硬件进行直接控制,而是通过设备驱动程序来完成对硬件的操作
驱动程序一般会以一个独立进程的方式存在
中断处理程序
当I/O任务完成时,I/O控制器会发送一个中断信号,系统会根
据中断信号类型找到相应的中断处理程序并执行
- 中断处理程序的处理流程

- 因此设备驱动程序、中断处理程序都会与硬件直接打交道,设备独立性及上层软件则不与外部设备硬件直接打交道
中断处理程序执行流程:
- 用户通过调用用户层软件提供的库函数发出的I/O请求:
- 用户层软件通过"系统调用"请求设备独立性软件层的服务
- 设备独立性软件层根据LUT调用设备对应的驱动程序
- 驱动程序向I/O控制器发出具体命令
- 等待I/O完成的进程应该被阻塞,因此需要进程切换,而进程切换必然需要中断处理
输入/输出管理
阻塞I/O:
- 应用程序发出I/O系统调用,进程需转为阻塞态等待
- 如字符设备接口,从键盘读一个字符进行get系统调用
非阻塞I/O:
- 应用程序发出I/O系统调用,系统调配可迅速返回,进程虚无阻塞等待
- 如块设备接口,往磁盘写数据进行write系统调用
输入/输出应用程序接口
用户层I/O软件通过系统调用去操作I/O硬件设备
- 但不同I/O设备所使用的系统调用参数不同
- 键盘、打印机不可寻址,每次读1个字符
- 磁盘等块设备可寻址,每次读/写1个快
- 网卡等网络控制器用于数据包的流转,参数中需要指明接收数据的对象
- 因此,用户层的应用程序无法使用一个统一的系统调用接口来完成所有类型设备的I/O
- 设备独立软件需要向上层I/O软件提供多种标准I/O类型的输入/输出接口,即多种标准的系统调用接口
字符设备接口:
- 操作字符型设备的标准接口
- get/put系统调用:
- 向字符设备读/写一个字符
块设备接口:
- 操作快设备的标准接口
- read/write系统调用:
- 向块设备的读写指针位置读/写多个字符
- seek系统调用:
- 修改读写指针位置
网络设备接口:又称为网络套接字socket接口
- socket系统调用:
- 创建一个网络套接字,需指明网络协议,如TCP/UDP
- bind系统调用:
- 将套接字绑定在某个本地端口
- connect系统调用:
- 将套接字连接到远程地址
- read/write系统调用:
- 从套接字读/写数据
网络设备接口执行过程:

- 主机1的进程P1与主机2的进程P3进行套接字连接
- 主机2中的P3进程进行socket系统调用,在系统主存内核空间中创建一个socket
- socket创建完成后,会返回给P3进程一个文件描述符FD,File Descriptor:一个直接指向该socket的指针
- P3获得socket的文件描述符后,进行bind系统嗲用,将该套接字与系统中的一个可用端口进行绑定,从而使得该套接字处于等待被连接状态,即监听状态
- 同理主机1的P1、P2进程也执行socket、bind系统调用分别创建一个套接字
- 假设P1进程进行connect系统调用,与主机2的P3进程的套接字进行远程连接,那么主机1和主机2就可以利用这两个套接字的连接进行数据通信
- 如P1执行connect(
fd,169.98.xxx.xxx:6666),与P3的套接字进行连接 - 套接字的连接位于应用层,在传输层可采用TCP/UDP协议
- 如P1执行connect(
- P1进程向P3进程点对点传输数据
- P1进行write系统调用,将P1进程用户空间中准备好的数据复制到套接字的缓冲区,复制过程由设备独立性软件实现
- 如P1执行write(
fd, xxxx),完成数据的写入
- 如P1执行write(
- 传输数据完成导套接字缓冲区的复制后,设备无关性软件会调用网络控制器驱动程序,交由该驱动程序将套接字缓冲区数据复制到网络控制器中
- 当网络控制器完成数据复制后,直接将数据包以特定的网络协议发送到网络链路中,网络协议确保了数据包的有效传输
- 主机2的网络控制器接收到发送来的数据包后,向CPU发出一个中断信号,引导至中断处理程序
- 随后中断处理程序会调用网络控制器驱动程序,完成网络控制器数据复制到指定套接字的过程
- 当P3进程想要读取传输过来的数据时,只需要进行read系统调用,则将套接字缓冲区中数据复制到P3进程的用户空间中
- 如P3执行read(
fd),完成数据的读入
- P1进行write系统调用,将P1进程用户空间中准备好的数据复制到套接字的缓冲区,复制过程由设备独立性软件实现
设备驱动程序接口
各个公司开发的设备驱动程序接口不同意,则操作系统很难调用驱动程序
- 因此操作系统会预先规定好设备驱动程序的接口标准,各个公司必须按要接口标准开发设备驱动。同时,不同操作系统,对设备驱动程序的接口也各不相同
- 设备厂商必须根据各种操作系统的接口要求,开发相应的设备驱动程序,设备才能被使用
I/O核心子系统
I/O软件层次结构自上而下包括:用户层软件 - 设别独立性软件 - 设备驱动程序 - 中断处理程序
- 其中设备独立性软件、设备驱动程序、中断程序属于操作系统的内核部分,即I/O系统或称I/O核心子系统
- 因此I/O核心系统主要实现设备独立性软件、设备驱动程序、中断程序三层的功能
I/O核心子系统常用的功能:
- I/O调度、设备保护、假脱机技术(SPOOLing技术)、设备分配与回收、缓冲区管理(即缓冲与高速缓存)
考研中重点掌握和理解的功能
- 假脱机技术,也叫SPOOLing技术,主要由用户层软件实现
- 假脱机技术需要请求磁盘设备设备独立性软件的服务
- 设备独立性软件实现I/O调度、设备保护、设备分配与回收、缓冲区管理(即缓冲与高速缓存)
- I/O调度:
- 通过某种算法确定一个好的顺序来处理各个I/O请求
- 如磁盘调度的先来先服务算法、最短训导优先算法、SCAN算法、C-SCAN算法、LOOK算法、C-LOOK算法
- 当多个磁盘I/O请求到来时,用某种调度算法确定满足I/O请求的顺序
- 同理打印机等设备也可以用先来先服务算法、优先级算法、短作业优先等算法来确定I/O调度顺序
- 设备保护:
- 操作系统需要实现文件保护功能,不同的用户对各个文件有不同的访问权限(如:只读、读和写等)
- 在UNIX系统中,设备被看做是一种特殊的文件,每个设备也会有对应的FCB
- 当用户请求访问某个设备时,系统根据FCB中记录的信息来判断该用户是否有相应的访问权限,以此实现"设备保护"的功能
- I/O调度:
假脱机技术(SPOOLing技术)
在计算机手工操作阶段,主机直接从I/O设备获得数据
- 由于设备速度慢,主机速度快,人机速度矛盾明显,主机要浪费很多时间来等待设备
计算机批处理阶段引入了脱机输入/输出技术(磁带实现)
- 脱机:
- 脱离主机的控制进行的输入/输出操作
- 作用:
- 缓解了CPU与慢速I/O设备的速度矛盾
- 脱机输入/输出过程实现了预输入、缓输出,且不需要CPU进行干预,解放了CPU可以去做其他任务
- 另一方面,即使CPU在忙碌,也可以提前将数据输入到磁带;即使慢速的输出设备正在忙碌,也可以提前将数据输出到磁带
脱机输入/输出技术执行过程:
- 用户需要进行输入的数据预先通过外围控制机输入到磁带中
- 在外围控制机的控制下,慢速输入设备的数据先被输入到更快速的磁带上。之后主机可以从快速的磁带上读入数据,从而缓解了速度矛盾
- 在输出过程也是类似,输出设备忙碌时,主机可将数据先输入到磁带中,通过外围控制机保证磁带数据持续通过输出设备输出
假脱机技术:
- 又称SPOOLing技术,通过软件的方式模拟脱机技术
- SPOOLing系统的组成:

- 在磁盘上开辟两个存储区域:
- 输入井:
- 模拟脱机输入时的磁带,用于收容I/O设备输入的数据
- 输出井:
- 模拟脱机输出时的磁带,用于收容用户进程输出的数据
- 输入井:
- 假脱机技术必须有多道程序技术的支持,系统会为此创建输入进程、输出进程
- 输入进程:
- 模拟脱机输入时的外围控制机
- 输出进程:
- 模拟脱机输出时的外围控制机
- 输入进程:
- 在内存中还会保留两块缓冲区域,作为输入、输出时的中转
- 输入缓冲区、输出缓冲区位于内存的缓冲区中
- 在输入进程的控制下,输入缓冲区用于暂存从输入设备输入的数据,之后再转存到输入井中
- 在输出进程的控制下,输出缓冲区用于暂存从输出井送来的数据,之后在传送到输出设备上
共享打印机
独占式设备:
- 只允许各个进程串行使用的设备。一段时间内只能满足一个进程的请求
- 如果独占设备允许同时处理多个进程的请求,会直接导致输入、输出内容混乱
共享设备:
- 允许多个进程"同时"使用的设备
- 宏观上同时使用,微观上可能是交替使用
- 可以同时满足多个进程的使用请求
打印机时中独占式设备
- 若进程1正在使用打印机,则进程2请求使用打印机时必然阻塞等待
- 但可以使用SPOOLing技术将打印机改造为共享设备

- 当多个用户进程提出输出打印的请求时,系统会答应它们的请求,但是并不是真正把打印机分配给他们,而是由假脱机管理进程为每个进程做两件事
- 在磁盘输出井中为进程申请一个空闲缓冲区(也就是说,这个缓冲区是在磁盘上的),并将要打印的数据送入其中
- 用户进程申请一张空白的打印请求表,并将用户的打印请求填入表中(其实就是用来说明用户的打印数据存放位置等信息的),再将该表挂到假脱机文件队列上
- 当打印机空闲时,输出进程会从假脱机文件队列的队头取出一张打印请求表
- 根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印
- 类似于进程挂起,通过这种方式可依次处理完全部的打印任务
虽然系统中只有一台打印机,但每个进程提出打印请求时,系统都会为在输出井中为其分配一个存储区(相当于分配了一个逻辑设备),使每个用户进程都觉得自己在独占一台打印机,从而实现对打印机的共享
SPOOLing 技术可以把一台物理设备虚拟成逻辑上的多台设备,可将独占式设备改造成共享设备
设备的分配与回收
设备分配时应考虑设备的固有属性、设备分配中的安全性、设备分配算法
设备的固有属性可分为三种:
- 独占设备:
- 一个时段只能分配给一个进程,如打印机
- 共享设备:
- 可同时分配给多个进程使用,如磁盘
- 各进程往往是宏观上同时共享使用设备,而微观上交替使用
- 虚拟设备:
- 采用SPOOLing 技术将独占设备改造成虚拟的共享设备,可同时分配给多个进程使用,如采用SPOOLing 技术实现的共享打印机
设备分配方式
从进程运行安全性角度上,设备分配有两种方式:
- 安全分配方式:
- 为进程分配一个设备后就将进程阻塞,本次I/O完成后才将进程唤醒,即一个时段内每个进程只能使用一个设备
- 优点:
- 破坏了"请求和保持"条件,不会死锁
- 缺点:
- 对于一个进程来说,CPU和I/O设备只能串行工作
- 不安全分配方式:
- 进程发出I/O请求后,系统为其分配I/O设备,进程可继续执行,之后还可以发出新的I/O请求,即一个进程可以同时使用多个设备
- 只有某个I/O请求得不到满足时才将进程阻塞
- 优点:
- 进程的计算任务和I/O任务可以并行处理,使进程迅速推进
- 缺点:
- 有可能发生死锁
- 解决方案可采用死锁避免、死锁的检测和解除
静态分配:
- 进程运行前为其分配全部所需资源,运行结束后归还资
动态分配:
- 进程运行过程中动态申请设备资源
设备分配管理数据结构

- 一个通道可以控制多个设备控制器,每个设备控制器可以控制多个设备
- 找到一个设备需要找到管理的设备控制器,而找到设备控制器需要找到对应的通道
- 为了方便设备管理,需要建立专门的数据结构表示这样的从属关系
设备控制表DCT:
- 操作系统为每个设备配置一张DCT,用于记录设备情况
- 设备类型:
- 如,打印机、扫描仪、键盘
- 设备标识符:
- 即物理设备名,系统确保每个设备的物理设备名唯一
- 设备状态:
- 忙碌、空闲、故障等
- 指向控制器表的指针:
- 每个设备由一个控制器控制,该指针可找到相应控制器的信息
- 重复执行次数或时间:
- 当重复执行多次I/O操作后仍不成功,才认为此次I/O失败,类似于计网里发送超时
- 设备队列的队首指针:
- 指向正在等待该设备的进程队列,由进程PCB组成的队列
- 系统会根据阻塞原因的不同,将进程PCB挂到不同的阻塞队列中,即插入该设备DCT的等待队列队尾
控制器控制表COCT:
- 每个设备控制器都会对应一张COCT,操作系统根据COCT的信息对控制器进行操作和管理
- 控制器标识符:
- 各个控制器的唯一ID
- 控制器状态:
- 忙碌、空闲、故障等
- 指向通道表的指针:
- 每个控制器由一个通道控制,该指针可找到相应通道的信息
- 控制器队列的对首指针:
- 同DCT中的指针
- 控制器队列的对尾指针:
- 指向正在等待该控制器的进程队列的队尾,由进程PCB组成队列
通道控制表CHCT:
- 每个通道都会对应一张CHCT,操纵系统根据CHCT的信息对通道进行操作和管理
- 通道标识符:
- 各个通道的唯一ID
- 通道状态:
- 忙碌、空闲、故障等
- 与通道连接的控制器表首址:
- 可通过该指针找到该通道管理的所有控制器相关信息(COCT)
- 通道队列的队首指针
- 通道队列的队尾指针
- 队首、队尾指针同COCT
系统设备表SDT:
- 记录了系统各种全部设备的情况,每个设备对应一个表项,每个表项包含以下类型:
- 设备类型:
- 如,打印机、扫描仪、键盘
- 设备标识符:
- 即物理设备名
- 设备控制表DCT:
- 指向设备对应的DCT表的指针
- 驱动程序入口
设备分配步骤
传统设备分配步骤
- 根据进程请求的物理设备名查找SDT
- 注:物理设备名是进程请求分配设备时提供的参数
- 根据SDT找到DCT,若设备忙碌则将进程PCB挂到设备等待队列中,不忙碌则将设备分配给进程
- 根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配给进程
- 根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程
只有设备、控制器、通道三者都分配成功时,这次设备分配才算成功,之后便可启动I/O设备进行数据传送
上述分配步骤缺点:
- 用户编程时必须使用物理设备名,底层细节对用户不透明,不方便编程
- 若换了一个物理设备,则程序无法运行
- 若进程请求的物理设备正在忙碌,则即使系统中还有同类型的设备,进程也必须阻塞等待
设备分配步骤改进:
- 建立逻辑设备名与物理设备名的映射机制,用户编程时只需提供逻辑设备名
改进后的设备分配步骤:
- 根据进程请求的逻辑设备名查找SDT
- 注:用户编程时提供的逻辑设备名其实就是"设备类型"
- 查找SDT,找到用户进程指定类型的、并且空闲的设备,将其分配给该进程。操作系统在逻辑设备表(LUT)中新增一个表项
- 只有系统查找到该类型的设备全部忙碌时,才会将该进程阻塞
- 根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配给进程
- 根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程
逻辑设备表LUT
| 逻辑设备名 | 物理设备名 | 驱动程序入口地址 |
|---|---|---|
| /dev/打印机 | 3 | 1024 |
| /dev/扫描仪 | 5 | 2046 |
| ... | ... | ... |
- 逻辑设备表LUT建立了逻辑设备名与物理设备名之间的映射关系
- 某用户进程第一次使用设备时使用逻辑设备名向操作系统发出请求
- 操作系统根据用户进程指定的设备类型(逻辑设备名)查找系统设备表,找到一个空闲设备分配给进程,并在LUT中增加相应表项
- 如果之后用户进程再次通过相同的逻辑设备名请求使用设备,则操作系统通过LUT表即可知道用户进程实际要使用的是哪个物理设备了,并且也能知道该设备的驱动程序入口地址
关于逻辑设备表的设置问题:
- 整个系统只有一张LUT:
- 各用户所用的逻辑设备名不允许重复,适用于单用户操作系统
- 每个用户一张LUT:
- 不同用户的逻辑设备名可重复,适用于多用户操作系统
(内存)缓冲区管理
缓冲区:
- 一个存储区域,可以由专门的硬件寄存器组成,也可利用内存作为缓冲区
- 使用硬件作为缓冲区的成本较高,容量也较小,一般仅用在对速度要求非常高的场合
- 如存储器管理中所用的联想寄存器,由于对页表的访问频率极高,因此使用速度很快的联想寄存器来存放页表项的副本
- 一般情况下,更多的是利用内存作为缓冲区,"设备独立性软件"的缓冲区管理就是要组织管理好这些缓冲区

缓冲区的作用:
- 缓和CPU和I/O设备之间速度不匹配的矛盾
- 减少对CPU的中断频率,放宽对CPU中断响应时间的限制
- 解决数据粒度不匹配的问题
- 输出进程每次可以生成一块数据,但I/O设别每次只能输出一个字符
- 提高CPU与I/O设备之间的并行性
若题目中没有特别说明,一个缓冲区的大小就是一个块
当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出
当缓冲区为空时,可以往缓冲区冲入数据,但必须把缓冲区充满以后,才能从缓冲区把数据传出
单缓冲
假设某用户进程请求某种块设备读入若干块的数据
- 若采用单缓冲的策略,操作系统会在主存中为其分配一个缓冲区

计算每处理一块数据平均的用时
- 假定一个初始状态,分析下次到达相同状态所需的时间,即为处理一块数据平均所需时间
- 单缓冲问题,可以假设初始状态为工作区满,缓冲区空
- CPU处理用户进程工作区的数据用时为C,缓冲区内数据传送到用户进程工作区用时为M,块设备将数据输入到主存缓冲区的用时为T

假设T > C
- 则CPU处理完数据后,暂时不能将下一块数据传送到工作区,必须等待缓冲区中充满数据
- 处理一块数据的平均用时为 T + M
假设T < C
- 则缓冲区中充满数据后暂时不能继续冲入下一块数据,必须等待CPU处理结束后将数据从缓冲区传送到工作区
- 处理一块数据的平均用时为 C + M
结论:
- 单缓冲策略,处理一块数据平均耗时
Max(C,T) + M
双缓冲
假设某用户进程请求某种块设备读入若干块的数据
- 若采用双缓冲的策略,操作系统会在主存中为其分配两个缓冲区

计算每处理一块数据平均的用时
- 假定一个初始状态,分析下次到达相同状态所需的时间,即为处理一块数据平均所需时间
- 双缓冲问题,可以假设初始状态为其中一个缓冲区满,另一个缓冲区空
- CPU处理用户进程工作区的数据用时为C,缓冲区内数据传送到用户进程工作区用时为M,块设备将数据输入到主存缓冲区的用时为T
假设T > C + M

- 缓冲区中的数据交给CPU处理完,必须等待快数据将另一块缓冲区充满才能进行后续的动作
- 处理一块数据的平均用时为 T
假设T < C + M

- 假设2T < 2M + C ,即/O设备将缓冲区1冲满时,缓冲区2的数据尚未取空,则I/O设备暂时不能冲入数据
- 总之,T < C + M意味这设备输入数据块的速度要比处理及处理数据快的速度更快
- 处理一个数据块平均用时为 C + M
结论:
- 双缓冲策略,处理一个数据块的平均耗时为 Max( T , C + M )
单/双缓冲在通信时的区别
两台机器之间通信时,可以配置缓冲区用于数据的发送和接受
若两个相互通信的机器只设置单缓冲区,在任意时刻只能实现数据的单向传输,即单工传输

若两个相互通信的机器设置双缓冲区,则同一时间可以实现双向的数据传输,即全双工传输

循环缓冲

将多个大小相等的缓冲区链接成一个循环队列
- 如图,橙色表示一充满数据的缓冲区,绿色表示空缓冲区
- 块设备向in指针指向的空缓冲区冲入数据,in指针指向下一个空缓冲区
- out指针指向的缓冲区向工作区传送数据,out指针指向下一个满缓冲区
循环缓冲仅了解,不需要分析处理一个数据块的平均耗时
缓冲池
缓冲池
- 由系统中共用的缓冲区组成,这些缓冲区按使用状况可以分为:
- 空缓冲队列
- 输入队列:装满输入数据的缓冲队列
- 输出队列:装满输出数据的缓冲队列
- 另外,根据一个缓冲区在实际运算中扮演的功能不同,又设置了四种工作缓冲区:
- hin缓冲区:用于收容输入数据的工作缓冲区
- sin缓冲区:用于提取输入数据的工作缓冲区
- hout缓冲区:用于收容输出数据的工作缓冲区
- sout缓冲区:用于提取输出数据的工作缓冲区

缓冲池工作过程:
- 当输入进程请求输入数据时
- 输入进程会从空缓冲队列中取出一块缓冲区作为收容输入数据的工作缓冲区hin
- 该缓冲区充满数据后,将其挂到输入队列队尾
- 当计算进程想要取得一块输入数据时
- 计算进程从输入队列中取得一块充满输入数据的缓冲区作为提取输入数据的工作缓冲区sin
- 该缓冲区读空后,挂到空缓冲区队列中
- 当计算进程想要将准备好的数据冲入缓冲区时
- 计算进程从空缓冲队列中取出一块作为收容输出的工作缓冲区hout
- 该缓冲区充满后,挂到输出队列队尾
- 当输出进程请求输出数据时
- 输出进程从输出队列中取得一块冲满输出数据的缓冲区作为提取输出数据的工作缓冲区sout
- 该缓冲区读空后,挂到空缓冲区队列
磁盘的结构

磁盘:
- 磁盘的表面由一些磁性物质组成,可以用这些磁性物质来记录二进制数据
- 磁盘的盘面被换分为一个个磁道,每一个"圈"就是一个磁道
- 最内侧磁道的扇区面积最小,因此数据密度最大
- 因此最内侧的数据密度大小与只做工艺密不可分,且越靠近内测的扇区发生物理损坏,损失的数据越多
- 一个个磁道又被划分为一个个扇区,每个扇区就是一个磁盘块,且每个扇区存放的数据量相同,如1KB
当磁盘进行读/写数据过程:
- 磁盘的磁头臂用于控制读/取内圈还是外圈的磁道,控制磁头移动到想要读/写的扇区所在磁道
- 磁盘由马达带动进行旋转后,目标扇区从磁头下面划过,完成对扇区的读/写操作
磁盘由多个盘片堆叠而成

- 因此可用(柱面号,盘面号,扇区号)来定位任意一个"磁盘块"
- 文件数据存放在外存中的实际物理块,这个块号就可以转换成(柱面号,盘面号,扇区号)的地址形式
- 可根据(柱面号,盘面号,扇区号)地址读取一个"块"
- 根据"柱面号"移动磁臂,让磁头指向指定柱面
- 激活指定盘面对应的磁头
- 磁盘旋转的过程中,指定的扇区会从磁头下面划过,这样就完成了对指定扇区的读/写
活动头磁盘:
- 磁盘的磁头可以移动,磁臂可以来回伸缩来带动磁头定位磁道
固定头磁盘:
- 磁盘的磁头不可以移动,这种磁盘每个磁道都有一个磁头
可换盘磁盘:
- 磁盘的盘片可以更换盘片
固定盘磁盘:
- 磁盘的盘片不可更换
固态硬盘
固态硬盘,SSD,Solid State Drives
- 原理:SSD基于闪存技术Flash Memory,属于电可擦除ROM,即EEPROM
- 由闪存翻译层、存储介质组成
- 闪存翻译层:负责翻译逻辑块号,找到对应的页Page
- 存储介质:和闪存类似,一般是多个闪存芯片Flash Chip。每个芯片包含多个块block,每个块包含页page
SSD读写性能特性
- 以页page为单位的读/写,相当于磁盘的扇区读写
- 以块block为单位擦除,其中的每页都可以写一次,读无限次
- SSD支持随机访问,系统给定一个逻辑地址,闪存翻译层可通过电路迅速定位到对应的物理地址
- SSD的读取数据速度快,但写入数据慢。要写的页如果有数据则不能直接写入,需要将块内的其他页全部复制到一个新的或者擦除过的块中,再写入新的页
- 一个数据存放的实际物理位置可能会变化,但是操作系统层面使用的逻辑块号对应到新物理地址过程全部由闪存翻译层完成,因此操作系统对物理地址的变化完全透明

- 固态硬盘的块大小大概16KB ~ 512KB,而页大小大约为512B ~ 4KB
- 系统要读/写的逻辑块号,如果读取的是磁盘,则读取的实际物理单位为块/扇区;而如果读取的是固态硬盘,则读取的实际物理单位是页
- 磁盘的磁道才对应固态硬盘的"块"
SSD与机械硬盘的区别

- SSD读写速度快,随机访问性能高,用电路控制访问位置;而机械硬盘通过移动磁臂旋转磁盘控制访问位置,由寻道时间和旋转延迟
- 固态硬盘的实际的读写单位为页page,在操作系统层面读写单位使用的是逻辑块;而磁盘的读写单位为扇区/块,固态硬盘和磁盘的块的概念并不相同
- SSD安静无噪声,耐摔抗震,能耗低,造假相比机械硬盘更贵
- SSD一个块备擦除次数过多或者重复写入同一个块过多次数,可能会坏块且无法修复;机械硬盘扇区不糊因为写入次数太多而坏掉,只会因为物理损坏而坏块
磨损均衡技术
将SSD的擦除平均分布在各个块上,以提升SSD的使用寿命
动态磨损均衡:写入数据时,优先选择累计擦除次数少的新闪存块
静态磨损均衡:SSD监测并自动进行数据分配、迁移,让老旧的闪存块承担以读为主的存储任务,让较新的内存块承接更多的写任务
SSD的寿命
某固态硬盘采用磨损均衡技术,大小为240B=1TB,闪存块的擦写寿命只有210=1K次。某男子
平均每天会对该固态硬盘写237B=128GB数据。在最理想的情况下,这个固态硬盘可以用多久?
- SSD采用磨损均衡技术,最理想情况下,SSD中每个块被擦除的次数都是完全均衡的
- 1TB/128GB=8,即平均每8天,每个闪存块需要擦除一次
- 每个闪存块可以被擦除1K次,因此,经过8K天,约23年后,该固态硬盘被男子玩坏
磁盘的管理
磁盘管理功能主要包括磁盘初始化、磁盘引导以及坏块的管理
磁盘初始化
磁盘初始化过程:
- 进行低级格式化(物理格式化),将磁盘的各个磁道划分为扇区
- 一个扇区通常可分为头、数据区域(如512B大小)、尾三个部分组成
- 管理扇区所需要的各种数据结构一般存放在头、尾两个部分,包括扇区校验码
- 扇区校验码用于校验扇区中的数据是否发生错误
- 如奇偶校验、CRC循环冗余校验码等
- 将磁盘分区/分卷,每个分区/分卷由若干个柱面组成,即人们熟悉的C盘、D、盘、E盘
- 进行逻辑格式化,创建文件系统
- 包括创建文件系统的根目录、初始化存储空间管理所用的数据结构
- 如位示图、空闲分区表
磁盘引导
磁盘完成物理格式化,分卷,以及逻辑格式化后,相关磁盘管理的数据结构写入到磁盘中,该过程包含在操作系统的安装中,即这些过程完成也代表着操作系统已经安装在磁盘中
磁盘引导过程:
- 计算机开机时,需要进行一系列的初始化工作,这些初始化工作通过执行初始化程序(自举程序)完成
- 自举程序可以存放在计算机的只读存储器ROM中,ROM中的数据在出厂时就写入且以后不能再修改
- ROM一般出厂时集成在主板上
- 为了方便自举程序的更新,在ROM中只存放很小的自举装入程序
- 开机时计算机先运行自举装入程序,通过执行该程序就可以找到引导块,并将完整的自举程序装入内存,完成初始化
- 完整的自举程序放在磁盘的启动块,即引导块上,启动块位于磁盘的固定位置
- 拥有启动分区的磁盘称为启动磁盘或系统磁盘,即熟知的C盘
磁盘坏块的管理
坏块:
- 坏了、无法正常使用的扇区
- 坏块属于硬件故障,操作系统无法通过软件形式修复,但应道将坏块进行标记,一面错误地使用到坏块
对于简单的磁盘,可以在逻辑格式化时(建立文件系统时)对整个磁盘进行坏块检查,标明哪些扇区是坏扇区
- 比如:在 FAT 表上标明
- 但在这种方式中,坏块对操作系统不透明
对于复杂的磁盘,磁盘控制器(磁盘设备内部的一个硬件部件)会维护一个坏块链表
- 在磁盘出厂前进行低级格式化(物理格式化)时就将坏块链进行初始化
- 扇区备用:
- 磁盘控制器会保留一些"备用扇区",用于替换坏块
- 这种处理方式中,坏块对操作系统透明
磁盘地址结构设计
磁盘固定使用(柱面号,盘面号,扇区号)表示物理地址
假设某磁盘有8个柱面/磁道,其中最内侧柱面/磁道号为0,4个盘面,8个扇区

- 则柱面可用3位二进制表示,盘面可用2位二进制表示,扇区可用3位二进制表示
如果改用(盘面号,柱面号,扇区号)表示物理地址,连续读取物理地址(000,00,000)~(000,01,111)的扇区
- (00,000,000)~(00,000,111 )转两圈可读完数据
- 之后再读取物理地址相邻的区域,即(00,001,000)~(00,001,111 )
- 需要启动磁头臂,将磁头移动到下一个磁道,再进行读取
如果使用原始物理地址结构(柱面号,盘面号,扇区号),连续读取物理地址(000,00,000)~(000,01,111)的扇区
- (000,00,000)~(000,00,111 )也只需由盘面0的磁头转两圈可读完数据
- 之后在读取物理地址相邻的区域,即(000,01,000)~(000,01,111 )
- 由于柱面号/磁道号相同,只是盘面号不同,不需要移动磁头臂,只需要激活相邻盘面的磁头即可继续读入
因此,读取地址连续的磁盘块时,采用(柱面号,盘面号,扇区号)的地址结构可以减少磁头移动消耗的时间
磁盘调度
一次磁盘读/写所需要的时间主要包括寻找/寻道时间、延迟时间、传输时间三部分
寻道时间T\(_s\):
- 在读/写数据前,将磁头移动到指定磁道所花的时间
- 启动磁头臂需要花费时间,假设耗时为s
- 移动磁头也需要花费时间。假设磁头匀速移动,每跨越一个磁道耗时为m,总共需要跨越n条磁道
- 整体寻道时间T\(_s\) = s + m*n
延迟时间T\(_R\):
- 通过旋转磁盘,使磁头定位到目标扇区所需要的时间
- 设磁盘转速为r(单位为转/秒,或转/分),则平均所需的延迟时间T\(_R\) = (1/2)*(1/r) = 1/2r
- 1/r就是转一圈需要的时间,找到目标扇区平均需要转半圈,因此乘1/2
- 硬盘的常见转速为5400转/分,7200转/分
传输时间T\(_t\):
- 从磁盘读出或向磁盘写入数据所经历的时间
- 假设磁盘转速为r,此次读/写的字节数为b,每个磁道上的字节数为N,则传输时间T\(_t\) = (1/r) * (b/N) = b/(rN)
- 每个磁道要存N字节的数据,b字节的数据需要b/N个磁道才能存储
- 读/写一个磁道所需的时间刚刚好优势一圈所需要的时间1/r
综上所述,总的平均存取时间T\(_a\) = T\(_s\) + T\(_R\) + T\(_t\) = T\(_s\) + 1/2r + b/(rN)
- 延迟时间T\(_R\)与传输时间T\(_t\)都与磁盘转速相关,且线性相关,转速是硬件的固有属性,因此操作系统无法对延迟时间和传输时间进行优化
- 而寻道时间与操作系统所采用的磁盘调度算法有直接关系,因此如果要降低磁盘的存取时间,需要优化磁盘的调度
磁盘调度算法
先来先服务FCFS:
- 更具进程请求访问磁盘的先后顺序进行调度,即排队服务
- 假设磁头的初始位置是100号磁道,有多个进程先后陆续请求访问55-58-39-18-90-160-150-38-184号磁道
- 按照FCFS规则,按照请求到达的先后顺序,磁头移动轨迹为100-55-58-39-18-90-160-150-38-184

- 磁头共移动了45 + 3 + 19 + 21 + 72 + 70 + 112 + 146 = 498个磁道
- 响应一个请求平均需要移动498/9 = 55.3 个磁道,即平均寻找长度为55.3
- 优点:
- 公平,如果请求访问的磁盘比较集中,算法性能还可以
- 缺点:
- 如果有大量进程竞争使用磁盘,请求访问的磁道很分散,FCFS在性能上会显得很差,寻道时间长
最短寻找时间优先SSTF:
- 优先处理的磁道是与当前磁头最近的磁道
- 可以保证每次寻道时间最短,但不能保证总的寻道时间最短
- 贪心算法思想,只选择局部最优,不考虑全局最优
- 假设磁头的初始位置是100号磁道,有多个进程先后陆续请求访问55-58-39-18-90-160-150-38-184号磁道
- 按照SSTF规则,按照请求到达的先后顺序,磁头移动轨迹为100-90-58-55-39-38-18-150-160-184

- 磁头总共移动了(100-18) + (184-18) = 248 个磁道
- 响应一个请求平均需要移动248/9 = 27.5 个磁道,即平均寻找长度为27.5
- 优点:
- 性能较好,平均寻道时间短
- 缺点:
- 可能产生饥饿现象
- 本例中,如果处理18号磁道的访问时又出现了一个38号磁道访问请求,处理38号请求后又出现18号访问请求...如果有源源不断地18、38号磁道的访问请求,150、160、184号此道的访问请求就永远得不到满足,从而产生饥饿
- 产生饥饿的原因在于磁头一直在一个小区域内来回移动
- 可能产生饥饿现象
扫描算法SCAN:
- 在SSRF的基础上改进,要求只有磁头移动到最外侧磁道的时候才能往内移动,移动到最内侧磁道的时候才能往外移动
- 假设某磁盘的磁道为0~200号,磁头的初始位置是100号磁道,且此时磁头正在往磁道号增大的方向移动。有多个进程先后陆续请求访问55-58-39-18-90-160-150-38-184号磁道
- 按照SCAN规则,按照请求到达的先后顺序,磁头移动轨迹为100-150-160-184-200(转向)-90-58-55-39-38-18
- 只有到了最边上的磁道才能改变磁头移动方向

- 磁头总共移动了(200-100) + (200-18) = 282个磁道
- 响应一个请求平均需要移动282/9 = 31.3 个磁道,即平均寻找长度为31.3
- 优点:
- 性能较好,平均寻道时间较短,不会产生饥饿现象
- 缺点:
- 只有到达最边上的磁道时才能改变磁头移动方向
- 事实上,本例中处理了184号磁道的访问请求之后就不需要在网右移动磁头了
- 只有到达最边上的磁道时才能改变磁头移动方向
LOOK调度算法:
- 在SCAN算法的基础上,如果在磁头移动方向上已经没有别的请求,就可以立即改变磁头移动方向
- 边移动边观察,因此叫LOOK算法
- 假设某磁盘的磁道为0~200号,磁头的初始位置是100号磁道,且此时磁头正在往磁道号增大的方向移动。有多个进程先后陆续请求访问55-58-39-18-90-160-150-38-184号磁道
- 按照LOOK规则,按照请求到达的先后顺序,磁头移动轨迹为100-150-160-184(转向)-90-58-55-39-38-18
- 如果在磁头移动方向上已经没有别的请求,就可以立即改变磁头移动方向

- 磁头总共移动了(184-100) + (184-18) = 250个磁道
- 响应一个请求平均需要移动250/9 = 27.5 个磁道,即平均寻找长度为27.5
- 优点:
- 比起SCAN算法,不需要每次都移动到最外侧或最内侧才改变磁头方向,使寻道时间进一步缩短
循环扫描算法C-SCAN:
- 为解决SCAN算法各个位置磁道响应频率不均匀的问题,规定只有磁头朝某个特定方向移动时才处理磁道访问请求,而返回时直接快速移动至起始短而不处理任何请求
- 假设某磁盘的磁道为0~200号,磁头的初始位置是100号磁道,且此时磁头正在往磁道号增大的方向移动。有多个进程先后陆续请求访问55-58-39-18-90-160-150-38-184号磁道
- 按照C-SCAN规则,按照请求到达的先后顺序,磁头移动轨迹为100-150-160-184-200(转向)-0-18-38-39-55-58-90
- 只有到了最边上的磁道才能改变磁头移动方向
- 磁头返回途中不处理任何请求

- 磁头总共移动了(200-100) + (200-0) + (90-0) = 390个磁道
- 响应一个请求平均需要移动390/9 = 43.3 个磁道,即平均寻找长度为43.3
- 优点:
- 比起SCAN算法来说,对于各个位置此道的响应频率更加平均
- 缺点:
- 比起SCAN算法,平均寻道时间更长
- 只有到达最边上的磁道时才能改变磁头移动方向,保留了SCAN算法的问题
- 磁头返回时其实只需要返回到18号磁道即可,不需要返回到最边缘的磁道
- 比起SCAN算法,平均寻道时间更长
C-LOOK调度算法:
- 解决C-SCAN算法必须到达嘴边磁道才转向的问题,如果磁头移动的方向上已经没有磁道访问请求了,就可以立即让磁头返回,并且磁头只需要返回到有磁道访问请求的位置即可
- 假设某磁盘的磁道为0~200号,磁头的初始位置是100号磁道,且此时磁头正在往磁道号增大的方向移动。有多个进程先后陆续请求访问55-58-39-18-90-160-150-38-184号磁道
- 按照C-SCAN规则,按照请求到达的先后顺序,磁头移动轨迹为100-150-160-184(转向)-18-38-39-55-58-90
- 如果在磁头移动方向上已经没有别的请求,就可以立即让磁头返回
- 磁头只需要返回到最靠近边缘的、并且需要访问的磁道上即可

- 磁头总共移动了(184-100) + (184-18) + (90-18) = 322个磁道
- 响应一个请求平均需要移动322/9 = 35.8 个磁道,即平均寻找长度为35.8
- 优点:
- 比起C-SCAN 算法来,不需要每次都移动到最外侧或最内侧才改变磁头方向,使寻道时间进一步缩短
减少磁盘延迟时间

- 假设要连续读取橙色区域2、3、4扇区
- 磁头读取一块内容,即一个扇区的内容后,需要一小段时间处理所读取到的信息
- 由于2、3号扇区相邻着排序,读完2号扇区后无法连续不断地读入3号扇区
- 盘片不可能此时停下等待2号扇区读完在重新开始转动,只能保持继续旋转,当2号扇区读完后,3号扇区再次划过磁头才能完成读入
- 因此,磁头读入一个扇区数据后需要一小段时间处理,如果逻辑上连续的扇区再物理上也相邻,则读入几个连续的逻辑扇区需要很长的延迟时间
交替编号策略:
- 让逻辑上相邻的扇区在物理上有一定的间隔,可以使读取连续的逻辑扇区所需要的延迟时间更小
错位命名策略:
- 假设相邻盘面相对位置相同处的扇区编号相同
- 由于所有扇区都是同时连轴转动的,因此再读完磁盘块(000,00,111)后,需要短暂的时间处理
- 而盘面又在不停地转动,因此当(000,01,000)第一次划过1号盘面的磁头下方时,不能马上读取数据,只能扇区再次划过磁头,即需要多转一圈,增加了延迟时间
- 如果采用错位命名
- 读取完磁盘块(000,00,111)后,还有一段时间处理,当(000,01,000)第一次划过1号盘面的磁头下方时,就可以直接读取数据,从而减少了延迟时间
本文来自博客园,作者:GK_Jerry,转载请注明原文链接:https://www.cnblogs.com/GKJerry/articles/18410827

浙公网安备 33010602011771号