本系列文章为408考研操作系统知识点整理仅涉及到一些重要的考研知识点并不是完全系统全面的知识,参考书目和视频资料:汤小丹 计算机操作系统(第四版),操作系统考研复习指导,B站王道考研操作系统视频课。

5.1.1 I/O设备

I/O设备分类

I/O(put/Output),意为输入和输出,I/O设备就是可以将数据输入到计算机,或者可以接受计算机输出数据的外部设备

(1)按使用特性分类
人机交互类外部设备:用于与计算机用户之间进行数据交互,如打印机、显示器、鼠标和键盘
这类设备的数据交换速度相对较慢,通常是以字节为单位进行的
存储设备:用于存储程序和数据,如磁盘、磁带、光盘等。
这类设备的数据交换速度相对较快,通常是以字节组成的为单位进行的
网络通信设备:用于与远程设备通信,如各种网络接口、调制解调器
这类设备速度介于前两类设备之间

(2)按传输速率分类
低速设备:传输速率仅为每秒几字节到数百字节,如磁盘、鼠标等
中速设备:传输速率为每秒数干字节到数万字节,如行式打印机、激光打印机等
高速设备:传输速率在数百干字节至干兆字节,如磁带机、磁盘机、光盘机等

(3)按信息交换单位分类
块设备:数据传输的单位是块;该类设备传输速率较高,可寻址(也即可以任意读写任一块);如磁盘等
字符设备:数据传输的单位是字符:该类设备传输速率较低,不可寻址,并且在输入输出时常采用中断驱动的方式;如交互式终端机、打印机等

I/O控制器

我们的电脑可以接入非常多的I/O设备,这些设备功能各异,控制方式更是大不相同,那么操作系统是如何实现这么多设备的统一管理呢?
为了屏蔽设备之间的差异,每个设备都有一个叫做O控制器(设备控制器)的组件,比如硬盘就有硬盘控制器,显示器就有视频控制器
操作系统控制I/O控制器,I/O控制器控制设备机械部件

I/O控制器内部含有三种寄存器,分别用于实现三种功能
控制寄存器:用于接受和识别CPU发出的命令;如CPU的发出的read/write命令
状态寄存器:用于向CPU报告设备的状态;如1表示空闲,0表示忙碌
数据寄存器:用于暂存CPU或设备发来的数据(也即数据交换功能);如打印的内容是“Hello”,CPU就要先发送一个H字符给对应的设备

另外,为了区分I/O控制器中的各个寄存器,也需要给各个寄存器设置一个特定的地址。I/O控制器通过CPU提供的地址来判断需要读/写的是哪个寄存器,也即I/O控制器还需要实现地址识别的功能

CPU与控制器的接口:用于实现CPU与控制器之间的通信。CPU通过控制器发出命令;通过地址线指明要操作的设备;通过数据线来取出或放入数据
控制器与设备的接口:用于实现控制器与设备之间的通信;控制器要向设备发出控制信息;设备要反馈自己的状态
I/O逻辑:负责接收和识别CPU的各种命令,并负责对设备发出命令

一个I/O控制器可能会对应多个设备
数据/控制/状态寄存器可能有多个,且这些寄存器都要有相应的地址,才便于CPU操作。

I/O软件层次结构

为了使复杂的I/O软件具有清晰的结构,在I/O软件中普遍采用层次式结构,将系统输入输出功能组织成一系列的细节,每层都利用其下次提供的服务,完成输入/输出功能中的某些子功能,并屏蔽这些功能的细节,然后向高层服务
一般会将层次划分如下

用户层软件

向上:用户层软件实现了与用户交互的接口,用户可以直接使用该层提供的、与I/O操作相关的库函数对设备进行操作
例如,使用C语言开发软件,可以使用printf函数向屏幕输出信息
向下:接着,用户层软件就会负责将用户的请求翻译为等价的系统调用
此时,库函数printf就会在其内部调用write()系统调用
需要注意printf内部实现其实较为复杂,并不是简简单单的调用一个write()就完事了

设备独立性软件

向上:向用户层提供统一的系统调用接口
向下:主要实现
设备保护:设备会被看作为一种特殊的文件,通过赋予文件权限也能间接保护设备
差错处理
设备的分配与回收
数据缓冲区管理
建立逻辑设备名到物理设备名的映射关系;根据设备类型调用相应的驱动程序:设备独立性软件需要通过逻辑设备表(LUT)来确定逻辑设备对应的物理设备,并找到该设备对应的设备驱动程序

设备驱动程序

I/O控制器不属于操作系统范畴,而属于硬件;设备驱动程序属于操作系统,操作系统的内核代码可以像本地调用一样使用设备驱动程序的接口,而设备驱动程序是面向设备控制器的代码,它发出操控设备控制器的指令后,才可以操作设备控制器
不同的设备控制器虽然功能不同,但是设备驱动程序会提供统一接口给操作系统,这样不同设备驱动程序,就可以以相同方式接入操作系统

(2)功能
向上:向上层提供一组标准接口,设备具体的差别被设备驱动程序封装,用于接受上层发来的抽象I/O请求,如read()和write()
向下:转换为具体要求后,发送给I/O控制器,控制设备工作

中断处理程序

当IO完成之后,IO控制器会发出一个中断信号,系统会根据中断信号类型转到中断处理程序并执行

5.2.1 高速缓存与缓存区

缓冲区是一个存储区域,可以由专门的硬件寄存器组成,也可以利用内存作为缓冲区
使用硬件作为缓冲区的成本较高,容量较小,一般仅用在对速度要求非常高的场合
更多情况下是利用内存作为缓冲区

(2)缓冲区作用
作用1:缓和CPU与I/O设备速度不匹配的矛盾

作用2:减少对CPU的中断频率,放宽对CPU中断响应时间的限制

作用3:解决数据粒度不匹配的问题
作用4:提高CPU与I/O设备之间的并行性

单缓冲

假设从磁盘把一块数据输入到缓冲区的时间为T,操作系统将该缓存区中的数据传送到用户区的时间为M,而CPU对这一块数据处理的时间为C

因此如果采用单缓冲策略,那么处理一块数据平均耗时为max(C,T)+M

双缓冲

因此如果采用双缓冲策略,那么处理一块数据平均耗时为max(T,C+M)

循环缓冲区:有时单缓冲和双缓冲并不能满足条件,以可以将多个大小相等的缓冲区链接成一个循环队列

缓冲池:和线程池等概念类似,它由系统中共用的缓冲区组成。这些缓冲区按照使用状况可以分为
空缓冲队列
装满输入数据的缓冲队列
装满输出数据的缓冲队列

另外,根据一个缓冲区实际运算中扮演的功能不同,又设置了四种工作缓冲区
用于收容输入数据的工作缓冲区(hin)
用于提取输入数据的工作缓冲区(sin)
用于收容输出数据的工作缓冲区(hout)
用于提取输出数据的工作缓冲区(sout)

5.2.2 设备的分配与回收

设备的固有属性
独占式设备:是指在申请设备时,若设备空闲,则将其独占,不再允许其他进程申请使用,一直等到该设备被释放才允许其他进程申请使用。例如打印机
共享设备(分时共享):可同时分配给多个进程使用,各个进程在宏观上是同时使用设备的,但在微观上是交替使用的。例如磁盘
虚拟设备:采用SPOOLing技术将独占设备改造成虚拟的共享设备,可同时分配给多个进程使用
例如用SPOOLing技术实现的共享打印机

设备分配管理中的数据结构
(1)设备控制表(DCT)
系统会为每一个设备配置一张设备控制表(DCT),用于记录设备情况

设备类型:记录它是什么类型的设备
设备标识符:也即物理设备名,系统中的每个设备的物理设备名唯一
设备状态:有忙碌/空闲故障等状态
指向控制器表的指针:每个设备由一个设备控制器控制,通过该指针可以找到相应的控制器
重复执行的次数或时间:当重复执行多次I/O操作仍然失败时,系统会认为此次I/O失败
设备队列的队首指针:指向正在等待该失败的进程队列

(2)控制器控制表(COCT)
每个设备控制器都会对应一张控制器控制表(COCT),操作系统根据COCT的信息可以对控制器进行操作和管理

控制器标识符:是各个控制器的唯一ID
控制器状态:忙碌/空闲故障
指向通道表的指针:每个控制器由一个通道控制,该指针可以找到相应通道的信息
控制器队列的队首指针
控制器队列的队尾指针:指向正在等待该控制器的进程队列

(3)通道控制表(CHCT)
每个通道都会对应一张通道控制表(CHCT),操作系统根据CHCT的信息对通道进行管理

通道标识符:各个通道的唯一ID
通道状态:忙碌/空闲故障
与通道连接的控制器表首址:可通过该指针找到该通道管理的所有控制器(COCT)相关信息
通道队列的队首指针
通道队列的队尾指针:指向正在等待该通道的进程对垒

(4)系统设备表(SDT)
系统设备表(SDT)记录了系统中全部设备的情况,每个设备对应一个表目

设备分配步骤如下,只有设备、控制器、通道三者都分配成功时,分配才算成功,接着便可以启动I/O设备进行数据传送
根据进程请求的物理设备名查找SDT
根据SDT找到DCT,若设备忙碌则将进程PCB挂到设备等待队列中,不忙碌则将设备分配个进程
根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配给进程
根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程

上面设备分配的缺点在于
用户编程时必须使用物理设备名,底层细节对用户不透明,不便于编程
若用户更换了一个物理设备,则程序无法运行
进程请求的物理设备正在忙碌,那么即使系统中还有同类型的设备,进程也必须要阻塞等待

改进方法就是建立逻辑设备名与物理设备名的映射机制,用户编程时只需要提供逻辑设备名
根据进程请求的逻辑设备名查找SDT(用户编程时提供的逻辑设备名其实就是设备类型)
查找SDT,找到用户进程指定类型且空闲的设备,将其分配给进程。操作系统在逻辑设备表(LUT)中新增一个表项
根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配给进程
根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程

5.2.3 假脱机(SPOOLing)技术

SPOOLingl的意思是外部设备同时联机操作,是一种用软件模拟的脱机技术,其组成如下

(1)输入井和输出井
输入井和输出井是指在磁盘上开辟出的两个存储区域
输入井模拟脱机输入时的磁盘,用于收容IO设备输入的数据
输出井模拟脱机输出时的磁盘,用于收容用户程序的输出数据
(2)输入缓冲区和输出缓冲区
输入缓冲区和输出缓中区是在内存中开辟的两个缓冲区
输入缓冲区用于暂存由输入设备送来的数据,之后再传送到输入井
输出缓冲区用于暂存从输出井送来的数据,之后再传送到输出设备

(3)输入进程和输出进程
输入进程模拟脱机输入时的外围控制机,将用户要求的数据从输入机通过输入缓冲区再送到输入井,当CPU需要输入数据时,直接将数据从输入井读入内存
输出进程模拟脱机输出时的外围控制机,将用户要求输出的数据先从内存送到输出井,待输出设备空闲时,再将输出井中的数据经过输出缓冲区送到输出设备

打印机是一种典型的独占式设备,在一段时间内只能供一个用户使用。而通过SPOOLing技术就可以将打印机改造为“共享设备”
当多个用户进程提出打印请求时,系统先会答应他们的请求,但并不是真正把打印机分配给他们,而是由假脱机管理进程为每个进程做两件事情
磁盘输出井中为每个进程申请一个空闲缓冲区,然后将打印的数据送入其中
为用户进程申请一张空白的打印申请表,并将用户的一些打印规格信息填入表中,再将该表挂到假脱机文件队列上
当打印机空闲时,输出进程会从文件队列的队头取出一张打印请求表,并根据表中要求将需要打印的数据从输出井送至输出缓冲区,再输出到打印机进行打印