操作系统理论 第六章(输入输出系统)—第七节(缓冲区管理)

写在前面:

  1. 本系列笔记主要以《计算机操作系统(汤小丹…)》为参考,大部分内容出于此书,笔者的工作主要是挑其重点展示,另外配合下方视频链接的教程展开思路,在笔记中一些比较难懂的地方加以自己的一点点理解(重点基本都会有标注,没有任何标注的难懂文字应该是笔者因为强迫症而加进来的,可选择性地忽略)。
  2. 视频链接:操作系统(汤小丹等第四版)_哔哩哔哩_bilibili

一、缓冲的引入

        为了缓和CPU和I/O设备速度不匹配的矛盾,提高CPU和I/O设备的并行性,在现代OS中,几乎所有的I/O设备与处理机交换数据时,都使用了缓冲区。

        除此之外,引入缓存的原因还有以下几点:

        ①减少对CPU的中断频率,放宽对CPU中断响应时间的限制

        ②提高CPU和I/O设备之间的并行性

        ③解决数据粒度不匹配的问题。

二、单缓冲区和双缓冲区

1、单缓冲区

(1)在单缓冲情况下,每当用户进程发出一I/O请求时,OS便在主存中为之分配一缓冲区。

(2)在块设备输入时,假定从磁盘把一块数据输入到缓冲区的时间为T,OS 将该缓冲区中的数据传送到用户区的时间为M,而CPU对这一块数据处理(计算)的时间为C。由于T和C是可以并行的,当T>C时,系统对每一块数据的处理时间为M+T,反之则为M+C,故可把系统对每一块数据的处理时间表示为Max(C, T)+M

(3)在字符设备输入时,缓冲区用于暂存用户输入的一行数据,在输入期间,用户进程被挂起以等待数据输入完毕;在输出时,用户进程将一行数据输入到缓冲区后,继续执行处理。当用户进程已有第二行数据输出时,如果第一行数据尚未被提取完毕,则此时用户进程应阻塞。

2、双缓冲区

(1)为了加快输入和输出速度,提高设备利用率,人们又引入了双缓冲区机制,也称为缓冲对换(Buffer Swapping)。在设备输入时,先将数据送入第一缓冲区,装满后便转向第二缓冲区,此时OS可以从第一缓冲区中移出数据,并送入用户进程,接着由CPU 数据进行计算。

(2)在双缓冲时,系统处理一块数据的时间可以粗略地认为是Max(C, T),如果C<T,可使块设备连续输入;如果C>T,则可使CPU不必等待设备输入。

(3)对于字符设备,若采用行输入方式,则采用双缓冲通常能消除用户的等待时间,即用户在输入完第一行后,在CPU执行第一行中的命令时,用户可继续向第二缓冲区输入下一行数据。

(4)如果在实现两台机器之间的通信时仅为它们配置了单缓冲,那么它们之间在任一时刻都只能实现单方向的数据传输。为了实现双向数据传输,必须在两台机器中都设置两个缓冲区,一个用作发送缓冲区,另一个用作接收缓冲区

三、环形缓冲区

1、环形缓冲区的组成

(1)多个缓冲区。在环形缓冲中包括多个缓冲区,其每个缓冲区的大小相同。作为输入的多缓冲区可分为三种类型——用于装输入数据的空缓冲区R、已装满数据的缓冲区G、计算进程正在使用的现行工作缓冲区C

(2)多个指针。作为输入的缓冲区可设置三个指针——用于指示计算进程下一个可用缓冲区G的指针Nextg、指示输入进程下次可用的空缓冲区R的指针Nexti、用于指示计算进程正在使用的缓冲区C的指针Current

2、环形缓冲区的使用

(1)Getbuf过程。当计算进程要使用缓冲区中的数据时,可调用Getbuf过程。该过程将由指针Nextg所指示的缓冲区提供给进程使用,相应地,须把它改为现行工作缓冲区,并令Current指针指向该缓冲区的第一个单元,同时将Nextg移向下一个G缓冲区;类似地,每当输入进程要使用空缓冲区来装入数据时,也调用Getbuf过程,由该过程将指针Nexti所指示的缓冲区提供给输入进程使用,同时将Nexti指针移向下一个R缓冲区。

(2)Releasebuf过程。当计算进程把C缓冲区中的数据提取完毕时,便调用Releasebuf过程,将缓冲区C释放,此时,把该缓冲区由当前(现行)工作缓冲区C改为空缓冲区R;类似地,当输入进程把缓冲区装满时,也应调用Releasebuf过程将该缓冲区释放,并将该缓冲区改为G缓冲区

3、进程之间的同步问题

        循环缓冲,可使输入进程和计算进程并行执行,相应的两个指针不断顺时针方向移动,这样就可能出现两种情况:

        ①Nexti指针追赶上Nextg 指针。这意味着输入进程输入数据的速度大于计算进程处理数据的速度,已把全部可用的空缓冲区装满,再无缓冲区可用,此时输入进程应阻塞,直到计算进程把某个缓冲区中的数据全部提取完,使之成为空缓冲区R,并调用Releasebuf过程将它释放时,才将输入进程唤醒。这种情况被称为系统受计算限制

        ②Nextg指针追赶上Nexti指针。这意味着输入进程输入数据的速度低于计算进程处理数据的速度,使全部装有输入数据的缓冲区都被抽空,再无装有数据的缓冲区供计算进程提取数据,这时计算进程只能阻塞,直至输入进程又装满某个缓冲区,并调用Releasebuf过程将它释放时,才去唤醒计算进程。这种情况被称为系统受I/O限制

四、缓冲池

1、缓冲池的组成

(1)缓冲池管理着多个缓冲区,每个缓冲区由用于标识和管理的缓冲首部以及用于存放数据的缓冲体两部分组成。缓冲首部一般包括缓冲区号、设备号、设备上的数据块号、同步信号量以及队列链接指针等。为了管理上的方便,一般将缓冲池中具有相同类型的缓冲区链接成一个队列,于是可形成以下三个队列:

空白缓冲队列emq。这是由空缓冲区所链成的队列,其队首指针F(emq)和队尾指针L(emq)分别指向该队列的首缓冲区和尾缓冲区。

输入队列inq。这是由装满输入数据的缓冲区所链成的队列,其队首指针F(inq)和队尾指针L(inq)分别指向输入队列的队首和队尾缓冲区。

输出队列outq。这是由装满输出数据的缓冲区所链成的队列,其队首指针F(outq)和队尾指针L(outq)分别指向该队列的首、尾缓冲区。

(2)除了上述三个队列外,还应具有四种工作缓冲区——用于收容输入数据的工作缓冲区、用于提取输入数据的工作缓冲区、用于收容输出数据的工作缓冲区、用于提取输出数据的工作缓冲区

2、缓冲区的工作方式

(1)收容输入。输入进程可调用Getbuf(emq)过程,从空缓冲队列emq的队首摘下一空缓冲区,把它作为收容输入工作缓冲区hin,然后把数据输入其中,装满后再调用Putbuf(inq,hin)过程将它挂在输入队列inq

(2)提取输入。计算进程可调用Getbuf(inq)过程,从输入队列inq的队首取得一缓冲区作为提取输入工作缓冲sin,计算进程从中提取数据,计算进程用完该数据后再调用Putbuf(emq,sin)过程将它挂到空缓冲队列emq

(3)收容输出。计算进程可调用Getbuf(emq)过程,从空缓冲队列emq的队首取得一空缓冲作为收容输出工作缓冲区hout,当其中装满输出数据后,再调用Putbuf(outq,hout)过程将它挂在outq末尾

(4)提取输出。输出进程可调用Getbuf(outq)过程,从输出队列outq的队首取得一装满输出数据的缓冲区作为提取输出工作缓冲区sout,在数据提取完后,再调用Putbuf(emq,sout)过程将它挂在空缓冲队列emq末尾

  • 19
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zevalin爱灰灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值