更多优质内容
请关注公众号

操作系统入门(二十一)IO系统之假脱机技术 SPOOLing、设备分配管理 和 IO缓冲区管理-张柏沛IT博客

正文内容

操作系统入门(二十一)IO系统之假脱机技术 SPOOLing、设备分配管理 和 IO缓冲区管理

栏目:其他内容 系列:操作系统入门 发布时间:2022-12-11 15:29 浏览量:939
本系列文章目录
展开/收起

上一节我们介绍了IO系统的分层、IO控制器以及IO控制的几种方式,今天我们将介绍 SPOOLing技术、 IO设备分配 和 IO缓冲区管理。


一、假脱机技术 (SPOOLing)

在介绍假脱机技术前,需要先了解IO设备可以按是否能共享分成 共享IO设备 和 独占IO设备。

独占式设备——只允许各个进程串行使用的设备。一段时间内只能满足一个进程的请求。

共享设备——允许多个进程“同时”使用的设备(宏观上同时使用,微观上可能是交替使用)。可以同时满足多个进程的使用请求。


我们知道如果多个进程需要申请使用一个独占的IO设备,这个独占的IO设备在被一个进程A使用的时候,其他进程需要等待进程A使用完这个IO设备并将其释放之后,才能获取到IO设备的使用权,这些进程在阻塞和等待的过程中无法继续完成手里的工作,这无疑会降低程序执行的并发度。


Spooling 是缓存多个进程对某个(独占)设备的IO请求以及IO数据(缓存到磁盘中),使得多个用户可以共享一台(独占)设备的技术。

这种技术降低了进程排队等待设备被释放的时间,把一台物理设备虚拟为多台逻辑IO设备,提高了设备的利用率(就和多道程序设计将一个物理CPU虚拟化为多个逻辑CPU一样的道理)。

一个SPOOLing系统可以向多个IO设备发送IO请求;SPOOLing系统是软件,属于IO系统的用户层(最顶层)。


SPOOLing系统的具体组成如下:



我们可以认为SPOOLing系统(假脱机系统)内保存着一个个待完成的IO任务,用户进程懒得排队等IO设备处理前面的IO请求,所以把IO任务以及数据先交给假脱机系统,由它把IO任务组织成队列慢慢处理,用户进程可以做别的事。


下面我们介绍下图中 SPOOLing系统 的各个组成部分(图中的输入输出进程不是用户进程,而是负责辅助SPOOLing系统工作的两个进程)。

1、输入井和输出井是磁盘上的两个存储区用来缓存IO数据(之所以用磁盘是因为IO数据可能太大,内存缓冲区放不下)。

输入井缓存IO设备输入到主机的数据。输出井缓存用户进程的输出数据。

输入井/输出井的数据以文件形式组织,一个用户进程的输出数据或IO设备的输入数据就是一个文件,称为井文件。井文件按照用户进程的IO请求顺序组织成队列(输入井和输出井各一个队列)。


2、假脱机文件队列(图中未画出)是保存在SPOOLing系统的IO任务队列,该队列保存在SPOOLing系统的内存中。


3、输入缓冲区(有2个)和输出缓冲区(有2个)是在内存中开辟的两个缓冲区,输入缓冲区存放IO设备输入到主机的数据(输入缓冲区1是IO设备把数据交付给输入井的缓冲,输入缓冲区2是输入井把数据交付给用户进程的缓冲)。输出缓冲区放用户进程的输出数据(输出缓冲区1是输出井把数据交付给IO设备的缓冲,输出缓冲区2是用户进程把数据交付给输出井的缓冲)。


4、输入进程将设备的输入数据传送到输入缓冲区1再放到输入井。输出进程将用户进程的输出数据从内存拷贝到输出井,等输出设备空闲时,把数据从输出井经输出缓冲区1送到输出设备。输入、输出进程是真正下达IO操作的进程。


假脱机技术的使用场景是优化用户进程对低速IO设备的IO操作。


SPOOLing系统优点有二:

提高了IO速度:原本全部数据在CPU与低速设备间交付完才算完成IO操作。现在优化成与高速的磁盘(输入输出井)交付。

将独占设备改造为共享设备:SPOOLing中,实际没有为任何进程分配目标IO设备,用户进程把IO请求交付给共享设备磁盘(输入输出井),没有直接交付给实际处理IO请求的独占设备。因此用户进程无需等待独占设备的释放,像是在并发的使用独占设备。


下面以共享打印机为例介绍SPOOLing的流程

打印机是种“独占式设备”,但是可以用 SPOOLing 技术改造成“共享设备”。


当多个用户进程提出输出打印的请求时, SPOOLing系统会答应它们的请求,但是并不是真正把打印机分配给他们, 而是由假脱机管理进程为每个进程做两件事:

(1)在磁盘输出井中为进程申请一个空闲缓冲区(也就是说,这个缓冲区是在磁盘上的),并将要打印的数据送入其中;

(2)为用户进程创建一个打印任务,任务内容包括具体IO请求的指令和参数(如输出数据位于输出井的哪个位置,设备地址等),再将该任务放到假脱机文件队列(打印任务队列)上。该队列位于内存中。

当打印机空闲时,输出进程会从文件队列的队头取出一个打印请求,并根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印。

这个例子中,假脱机管理进程是任务的生产者,输出进程是任务的消费者,也是真正下达打印操作(IO操作)的进程。假脱机管理进程只负责和用户进程通信。实际我们可以把输入输出进程和管理进程抽象的看成是几个守护进程在完成 SPOOLing 与用户进程的交互工作 以及 数据在井与设备间的拷贝工作,没必要分的那么细。


二、设备分配

设备分配是IO系统中“设备独立性软件层”要做的事情。

设备分配应考虑的因素包括:设备的属性、分配算法、安全性(即按照这种分配方式分配的话,进程是否会死锁)。


设备属性包含独占设备、共享设备和虚拟设备(如SPOOLing系统改造后的设备),根据不同属性实行不同的分配方式。


从进程运行的安全考虑,可分为

安全分配方式:为进程分配一个设备后(如打印机)就将进程阻塞,本次I/O完成后才将进程唤醒。好处是进程阻塞后就不会请求其他IO设备,不会死锁。缺点是进程和IO设备串行工作。

不安全分配方式:进程发出I/O请求后,系统为其分配I/O设备,进程可继续执行,之后还可以发出 新的I/O请求。只有某个I/O请求得不到满足时才将进程阻塞。有可能发生死锁(采用死锁避免、死锁的检测和解除)


静态分配和动态分配

静态分配:进程运行前为其分配所有所需资源(如果有一个资源未就绪,就会阻塞进程),运行结束后归还。

动态分配:进程运行过程中动态分配资源。


IO系统涉及设备分配的数据结构如下:

系统为每个物理设备配置一个设备控制表,为一个IO控制器配置一个控制器控制表,为一个通道配置一个通道控制表,为IO系统中所有的设备分配一个系统设备表


由于一个通道对应多个控制器,一个控制器可以对应多个设备,因此一个通道控制表下有多个控制器控制表(以链表形式组织),一个控制器控制表下有多个设备控制表(以链表形式组织)。



设备分配管理中的数据结构


1、设备控制表(DCT)


2、控制器控制表(COCT)



3、通道控制表(CHCT)



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




设备分配步骤

1、IO请求到达“设备独立性软件层”后,系统根据IO系统调用中的物理设备名参数查找SDT。以物理设备名找到SDT中符合的一个表项,获取表项中的DCT地址,也获取其驱动程序入口,以便设备最终分配成功后执行驱动程序。



2、根据DCT地址读取DCT,若设备忙碌则将进程PCB挂到DCT的设备等待队列中,不忙碌则将设备分配给进程。


3、根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配 给进程。

4、根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程。


一层层的从设备找到控制器再找到通道。

只有设备、控制器、通道三者都分配成功时,这次设备分配才算成功,之后便可启动I/O设备 进行数据传送。


该分配方式是假设用户编程使用物理设备名对设备请求,有以下缺点:

A 如果主机换了一个物理设备(找不到这个物理设备了),则程序无法运行。

B 如果进程请求的物理设备在忙,即使系统中还有同类型的设备(例如电脑有3台打印机,进程A请求打印机1,进程B也请求打印机1,B就阻塞了,最好是有个逻辑设备名可以代表这3台物理设备),进程也会阻塞等待。


改进方法:建立逻辑设备名与物理设备名的映射机制,用户编 程时只需提供逻辑设备名。


注意:逻辑设备名不是指代具体某一台设备,而是同一类型的所有物理设备,例如 /dev/printer 这个逻辑设备名指代所有打印机。

实际上,SDT表项中的“设备类型”字段就是逻辑设备名。


系统会为每个用户维护一个逻辑设备表(LUT),记录着某个用户使用的逻辑设备名所对应的物理设备名或者物理设备对应的SDT表项的指针。该表中不会出现重复的逻辑设备名的行。不同LUT中相同逻辑设备名可以对应到不同物理设备。


改进后的分配步骤:

1、根据IO请求中的逻辑设备名(设备类型)查找SDT的指定行表项。如果该表项下的设备不空闲,则继续在SDT往下找。

2、找到用户进程指定类型的、并且空闲的设备,将其分配给该进程。操作系统在逻辑设 备表(LUT)中新增一个表项。

之后的步骤同上。

用户进程第一次使用设备时要根据逻辑设备名遍历SDT,建立LUT的表项。之后通过逻辑设备名查LUT表即可知道用户进程实际要使用的是哪 个物理设备以及它的SDT表项位置。



三、IO缓冲管理

IO缓冲区管理也是“设备独立性软件层”实现的。

缓冲区是一个缓存区域,可以用专门的硬件寄存器组成,也可用内存作为缓冲区。IO缓冲主要是内存。

输出数据时CPU可以把输出数据快速放到缓冲区,之后做别的事,慢速的IO设备可以慢慢从缓冲区取走数据;输入数据时同理。




缓冲区作用:

1、缓和CPU和IO设备速度不匹配的矛盾,提高CPU和IO的并行性。

2、减少CPU中断频率,放宽CPU响应中断的时间(对于字符设备而言,增设缓冲区可以减少CPU中断频率)

3、解决数据粒度不匹配问题(如输出进程每次可以生产一块数据,但IO设备每次只能输出一个字符)。


缓冲区的特点是,缓冲区必须要充满之后才能从缓冲区把数据传出到其他地方。缓冲区的数据传出的过程中,不能往缓冲区冲入数据。

也就是说,一个缓冲区在被输入满之前他只能是一个输入缓冲区,不能输出。一个缓冲区在输出为空缓冲区之前它只能是一个输出缓冲区,不能接受其他输入数据。



单缓冲

假设某用户进程请求某种块设备读入若干块的数据。若采用单缓冲的策略,操作系统会在主存中为 其分配一个缓冲区(大小为一块)。



首先,块设备的一块数据进入到缓冲区之后(填满缓冲区),数据还只是在内核的内存中,缓冲区满了之后,数据会从缓冲区拷贝到用户进程的内存(假设用户进程的工作区大小也是一块数据),随后用户进程处理这块数据,处理完之后用户进程清空工作区。


假设块设备拷贝一块数据到缓冲区花费时间 T。

缓冲区拷贝所有数据(缓冲区大小是一块数据)到用户进程的时间是 M,CPU处理用户进程的一块数据时间为 C。


那么每处理一块数据平均需要时间N为多少?假设初始状态是工作区满,缓冲区空,则N等于下一次工作区满,缓冲区空所花的时间。

因为工作区满足一个块,所以用户进程可以开始处理数据;因为缓冲区空,所以块设备可以向缓冲区传输数据。这两个动作是并行的。有以下几种情况:

1、T > C时,用户进程先处理完数据,并把工作区清空(当前时刻为C),但缓冲区还未填满,因此还不能向用户进程传输。等到缓冲区清空了才能往用作区输送数据(当前时刻为T)。缓冲区传送完数据到用作区之后,就回到了初始状态。因此 N = T+M。




2、T<C时,由于缓冲区充满要早于CPU处理用户进程中的数据,因此缓冲区中 冲满数据后暂时不能 向用户进程传输数据(因为工作区内存大小只有一个块),块设备也不能向缓冲区继续冲入下一块数据, 必须等待CPU处理结 束后将数据从缓冲区 传送到工作区。
该情况下 N = C + M


结论:在工作区内存大小等于缓冲区内存大小的情况下,采用单缓冲策略,处理一块数据平均耗时 Max(C, T)+M。



双缓冲区
假设某用户进程请求某种块设备读入若干块的数据。若采用双缓冲的策略,操作系统会在主存中为 其分配两个缓冲区(假設一个缓冲区的大小就是一个块)。
则块设备既可以往缓冲区1输入数据,也可以往缓冲区2输入数据,但两者只能是串行的。但如果缓冲区1满了,要向工作区输送数据,则块设备往缓冲区2发送数据和缓冲区1往工作区发送数据是并行的。


使用单/双缓冲在通信时的区别:
两台机器(或者进程)之间通信时,如果为每个通信进程配置一个单缓冲区用于数据的发送和接受,那么在任一时刻只能实现数据的单向传输。A在缓冲发送数据的时候,由于A的缓冲区中有数据,因此B无法发送数据给A(否则B到达A的数据和A准备发送的数据会在A的缓冲区中混在一起),必须A发送完数据给B之后,B才能发送数据给A。而且B的缓冲区也必须没有数据,A才能发送数据到B的缓冲区。


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



循环缓冲区

是指分配多个缓冲区,这些缓冲区链接成一个成环的队列,维护两个指针,in指针表示下一个可以冲入数据的空缓冲区,out指针是下一个可以取出数据的满缓冲区。



缓冲池

在用户进程进行IO操作的时候,IO系统将分配多个缓冲区给该用户进程,这些缓冲区分为3类:其中空缓冲区们组成空缓冲队列,装满了数据待输出的缓冲区们组成了输出队列,装满了输入数据的缓冲区们组成了输入队列。


此外,系统会分配一个缓冲池给该用户进程,该缓冲池包含4个缓冲区指针。



1、当用户进程请求输入,系统从空缓冲队列移除队首节点A,并让hin指向该缓冲区节点A。IO设备会将输入数据输入hin指针所指的缓冲区A。

当这个hin指针所指的缓冲区A填满之后,它会转移到输入队列的尾部。如果IO设备的数据还没传输完,它会继续从空缓冲队列弹出一个队首B,让hin指向这个缓冲区B,IO设备继续往缓冲区B填充数据。

如果用户进程想要获取输入数据,它会从sin指针所指的一个缓冲区取出数据,sin指针指向输入队列的队首C。当队首缓冲区C的数据被取走后,该缓冲区会转移到空缓冲区队列的队尾。sin指针指向输入队列的新队首D,用户进程继续从新队首中取出数据。

2、当用户进程想要将准备好的数据冲入缓冲区,以及用户进程请求输出数的过程和上述过程相似,hout指向空缓冲队列的缓冲区,sout指向输出队列的首部缓冲区。提高了IO操作过程中数据拷贝的并行性。




更多内容请关注微信公众号
zbpblog微信公众号

如果您需要转载,可以点击下方按钮可以进行复制粘贴;本站博客文章为原创,请转载时注明以下信息

张柏沛IT技术博客 > 操作系统入门(二十一)IO系统之假脱机技术 SPOOLing、设备分配管理 和 IO缓冲区管理

热门推荐
推荐新闻