之前都是对于计算机主机内部的,当前节则是主机外部,硬件设备的管理。
“I/O
"就是"输入/输出”(Input/Output
)。
I/O
设备就是可以将数据输入到计算机或者可以接收计算机输出数据的外部设备,属于计算机中的硬件部件。
接下来看一下输入设备、输出设备、既可输入也可输出的设备:
Unix
系统将外部设备抽象为一种特殊的文件,用户可以使用与文件操作相同的方式对外部设备进行操作。
Write操作
:向外部设备写出数据。Read操作
:从外部设备读入数据。人机交互类外设:鼠标、键盘、打印机等,用来人机交互。(数据传输速度会比较慢,数据传输是以字节、几十字节为单位)
存储设备:移动硬盘、光盘等,主要用于数据存储。数据传输速度快。
网络通信设备:调制解调器、路由器等,用于网络通信,传输速度介于上面两种速度之间。
低速设备:鼠标、键盘,传输速率为每秒几个-几百字节。
中速设备:如激光打印机等,传输速率为每秒数千-上万个字节。
高速设备:如磁盘等,传输速率为每秒数千字节-千兆字节的设备。
块设备:如磁盘等,数据传输的基本单位是"块"。传输速率较高,可寻址,即对它可随机地读/写任一块。
字符设备:鼠标、键盘灯,数据传输的基本单位是字符。传输速率慢,不可寻址,在输入/输出时长采用中断驱动方式。
I/O设备的机械部件:主要用来执行具体的I/O操作。
I/O设备的电子部件通常是一块插入主板扩充槽的印刷电路板。
电子部件
:就是一个印刷电路板,CPU是无法直接控制这些设备的机械部件,需要通过电子部件来间接的控制这些机械部件,作为CPU和I/O设备机械部件之间的终结,用于实现CPU对设备的控制。
这个电子部件也称为I/O控制器(又称设备控制器):CPU可控制I/O控制器,又由I/O控制器来控制设备的机械部件。
I/O控制器的功能:
1、接收和识别CPU发出的命令:如CPU发来read/write命令,I/O控制器中会有相应的控制寄存器来存放命令和参数。
2、向CPU报告设备的状态:I/O控制器中会有相应的状态寄存器,用于记录I/O设备的当前状态,如:1表示空闲,0表示忙碌。
3、数据交换:I/O控制器会设置相应的数据寄存器,输出时,数据寄存器用于暂存CPU发来的数据,之后再由控制器传送设备。输入时,数据寄存器用于暂存设备发来的数据,之后CPU从数据寄存器当中取走数据。
4、地址识别:类似于内存的地址,为了区分设备控制器的各个寄存器,也需要给各个寄存器设置一个特定的"地址"。I/O控制器通过CPU提供的"地址"来判断是哪个寄存器。
I/O控制器组成主要分为三个:CPU与控制器的接口、I/O逻辑、控制器与设备的接口。
CPU与控制器的接口
:用来实现CPU与控制器之间的通信。CPU通过控制器发出命令;通过地址线来指明要操作的设备;通过数据线来取出(输入)数据,或放入(输出)数据。I/O逻辑
:负责接收和识别CPU的各种命令(如地址译码),并负责对设备发出命令。控制器与设备的接口i
:用于实现控制器与设备之间的通信。控制器会有多个与设备之间的接口,也就是一个I/O控制器可能会负责控制多个具体的I/O设备。为了区分此时要操作的哪个设备同样要进行编址。
实现过程:
数据寄存器
中,之后I/O逻辑会从数据寄存器当中取得CPU输出的数据。CPU发出的I/O指令一些相应参数会放到控制寄存器
当中,那么I/O逻辑就也可以从控制寄存器中读出一些参数。小细节:
1、一个I/O控制器可能会对应多个设备。
2、数据寄存器、控制寄存器、状态寄存器可能由多个(如:每个控制/状态寄存器对应一个具体的设备),且这些寄存器都要有相应的地址,才能方便CPU操作。对于地址编址分为两种方式。
内存映像I/O
:控制器中的寄存器与内存地址统一编址。
优点:简化了指令,可以采用对内存进行操作的指令来对控制器进行操作。
寄存器独立编址
:寄存器独立编址中,控制器中的寄存器使用单独的地址。
缺点:需要设置专门的指令来实现对控制器的操作,不仅要指明寄存器的地址,还要指明控制器的编号。
1、完成一次读/写操作的流程(以读操作为例)
若是进行读指令:
对于上面所描述的流程图如下图所示:
为什么读入到CPU的数据寄存器之后还需要写入到存储器呢?
2、CPU干预的频率
很频繁,I/O操作开始之前、需要之后需要CPU介入,并且在等待I/O完成的过程中CPU需要不断的轮询检查。
3、数据传送单位
每次读/写一个字。
4、数据的流向
读操作(数据输入):I/O设备—>CPU—>内存。(其中CPU指的是CPU的寄存器)
写操作(数据输出):内存—>CPU—>I/O设备。
每个字的读/写都需要CPU的帮助。
5、主要缺点和主要缺点
优点:实现简单。在读/写指令之后,加入实现循环检查的一系列指令接口。所以称为"程序直接控制方式"。
缺点:CPU和I/O设备只能串行工作,CPU需要一直轮询检查,长期处于盲等状态,CPU利用率低。
1、完成读/写操作的流程,关键:中断。
执行流程:
注意:
1、CPU会在每个指令周期的末尾检查中断。
2、中断处理过程中需要保存、恢复进程的运行环境,这个过程是需要一定时间开销的。可见,如果中断发生的频率太高,会降低系统性能。
2、CPU干预的频率
每次I/O操作的开始之前,完成之后需要CPU介入。
等待I/O完成的过程中CPU可以切换到别的进程执行(此时CPU与I/O是可以进行并行工作的)。
3、数据传送的单位
每次读/写一个字
4、数据的流向
读操作(数据输入):I/O设备—>CPU—>内存
写操作(数据输出):内存—>CPU—>I/O设备
5、主要缺点和主要优点
优点:与"程序直接控制方式"相比,在"中断驱动方式"中,I/O控制器会通过中断信号主动报告I/O已完成,CPU不再需要不停的轮询。CPU和I/O设备并行工作,CPU利用率得到明显提升。
缺点:每个字在I/O设备与内存之间的传输,都需要经过CPU,而频繁的中断处理会消耗较多的CPU时间。
提出思考:可以看到读/写过程都经过了CPU,能够将其中的中转步骤取消呢?DMA方式。
与"中断驱动方式"相比,DMA方式(Direct Memory Access,直接存储器存取,主要用于块设备的I/O控制)有这样几个改进:
①数据的传输单位是"块",不再是一个字、一个字的传送。
②数据的流向是从设备直接放入内存,或者从内存直接到设备,不再需要CPU作为"快递小哥"。
③仅在传送一个或多个数据块的开始和结束时,才需要CPU干预。
1、完成读/写操作的流程
1、CPU会给I/O模块发出一个读或者写一个块的指令,之后CPU就可以去做其他事情,I/O设备开始完成一系列的读/写操作。
2、CPU指定的工作任务I/O设备都完成之后,会由DMA控制器向CPU发出一个中断信号。
3、此时CPU又介入处理这个中断,在CPU发出读或者写指令的时候,需要说明此次要读入或者写出的到底有多少数据,这些数据应该存放在内存什么位置,数据在外部设备上应该存放在什么位置。
4、此时DMA控制器会根据CPU提出的要求完成数据的读/写工作,整块数据的传输完成之后,才会向CPU发出中断信号,要求CPU来介入中断。
为了实现控制器和CPU之间通信,会在DMA控制器中设置一系列的寄存器,接着CPU可以通过系统总线来读或者写其中的某一些寄存器当中的内容。
DR(Data Register,数据寄存器)
:暂存从设备到内存,或从内存到设备的数据。MAR(Memory Address Register、内存地址寄存器)
:在输入时,MAR表示数据应放在内存中的什么位置;输出时MAR表示要输出的数据放在内存什么位置。DC(Data Counter,数据计数器)
:表示剩余要读/写的字节数。CR(Commend Register,命令/状态寄存器)
:用于存放CPU发来的I/O命令,或设备的状态信息。这些寄存器是最主要的主机与控制器之间的接口。
补充点:
注意:实际DMA控制器并不是每次读入一整块数据,也是一个字、一个字读的,然后每次读入的一个字都是会先存放在DR数据寄存器当中,接着再从DR写入到内存中。
2、CPU干预的频率
仅在传送一个或多个数据块的开始和结束时,才需要CPU干预。
3、数据传送的单位
每次读/写一个或多个块。
注意:每次读写的只能是连续的多个块,且这些块读入内存在内存中也必须是连续的。
4、数据的流向(不再需要经过CPU)
读操作(数据流向):I/O设备—>内存
写操作(数据输出):内存—>I/O设备
5、主要优点与缺点
优点:数据传输以"块"为单位,CPU介入频率降低。数据的传输不再需要先经过CPU再写入内存,数据传输效率进一步增加。CPU与I/O设备的并行性得到提升。
缺点:CPU没发出一条I/O指令,只能读/写一个或多个连续的数据块。
可改进的特点:如果要读/写多个和离散存储的数据块,或者要将数据分别写到不同的内存区域中,CPU要分别发出多条I/O指令,进行多次中断处理才能完成。
通道
:一种硬件,可以理解为"弱鸡版的CPU"。通道可以识别执行一系列的通道指令。
1、完成一次读/写操作的流程
1、CPU向通道发出I/O指令,指明通道程序在内存中的位置,并指明要操作的是哪个I/O设备,之后CPU就切换到其他进程中执行。
2、通道执行内存中的通道程序(其中指明了要读入/写出多少数据,读/写的数据应放在内存的什么位置等信息)。
通道会根据CPU的指示去找到此次要执行通道程序存放在内存当中什么位置。通道实际上是可以理解为一个任务清单,这个任务清单是一系列通道指令的集合。
3、通道执行完规定的任务后会向CPU发出中断信号,之后CPU对中断进行处理。
2、CPU干预的频率
极低,通道会根据CPU的指示执行相应的通道程序,只有完成了一组数据块的读/写后才需要发出中断信号,请求CPU干预。
3、数据传送的单位
每次读/写一组数据块。
4、数据的流向(在通道的控制下进行)
读操作(数据输入):I/O设备—>内存
写操作(数据输出):内存—>I/O设备
5、主要缺点和主要优点
优点:CPU、通道、I/O设备可并行工作,资源利用率很高。
缺点:实现复杂,需要专门的通道硬件支持。
重点关注软件层面实现的功能,分析从下到上顺序各个功能。
用户层软件:需要请求操作系统提供服务,向下进行系统调用。会将这一层称作是系统调用处理层。
设备独立性软件:又被称为无关性软件,与设备的硬件特性无关的功能都在这一层实现。主要负责对硬件设备的具体控制,将上层发出的一系列命令(如read/write)转换为特定设备"能听得懂"的一系列操作。包括设置设备寄存器,检查设备状态等。
职责包含:系统调用参数翻译成设备操作命令的工作。
主要实现的功能:
1、向上层提供统一的调用接口(如:read/write系统调用)。
2、设备保护,原理类似于文件保护。设备看做是一种特殊的文件,不同用户对各个文件的访问权限是不一样的,同理对设备的访问权限也不一样。
3、差错处理:用于对一些设备的错误进行处理。
4、设备的分配与回收:大多设备都是临界资源,不能够分配给多个设备使用。操作系统要对设备这种资源进行分配与回收的管理。
5、数据缓冲区管理:可以通过缓冲技术屏蔽设备之间数据交换单位大小和传输速度的差异。
6、建立逻辑设备名到物理设备名的映射关系:根据设备类型选择相应的驱动程序。
很多操作系统会将设备当做一种特殊文件,文件也有一个存储的路径,每一个表象记录了逻辑设备名到物理设备名的一个映射关系,其中对于不同类型的I/O设备需要使用不同的驱动程序处理。
操作系统采用两种方式管理逻辑设备表(LUT):
方式一:整个系统只设置一张LUT,意味着所有用户不能使用相同的逻辑设备名,因此这种方式只适用于单用户操作系统。
方式二:给每个用户设置一张LUT,各用户使用的逻辑设备名可以重复,适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程,而LUT就存放用户管理进程的PCB中。
原因:各种各样的额设备、外形不同,各自的电子部件(I/O控制器)也有可能不同。
例如佳能打印机电子部件设计如下图:有两个数据寄存器,对应的控制寄存器1表示忙碌,0表示空闲
惠普的如下(举例子):只有一个数据寄存器,对应的控制寄存器0表示忙碌,1表示空闲
不同设备的内部硬件特性也不同,这些特性只有厂家才知道,因此厂家需要提供与设备相对应的驱动程序,CPU执行驱动程序的指令序列来完成设置寄存器,检查设备状态等工作。
结论:各种设备内部硬件特性不一样,所以必须执行与它对应的特定驱动程序,才可以正常完成对这个设备硬件的控制。
主要负责:对硬件设备的具体控制,将上层发出的一系列命令(如read、write)转换成特定设备"能听得懂"的一系列操作。
包括设置设备寄存器、检查设备状态等。
当硬件设备完成I/O操作之后,它会发出一个中断信号,作为应答,那么系统会根据这个中断信号的类型来找到与这个中断信号对应的中断处理程序。
中断处理程序处理流程:
1、根据中断处理程序进行处理,从I/O控制器或者设备控制器当中读出设备状态来判断这次的I/O是不是正常的结束。
2、当中断处理程序把这一次要输入的数据放入到内存之后,会交由设备驱动程序对这些数据进一步的处理,等待设备驱动程序处理完会交由上一层的设备独立性软件再进行进一步的处理,最后一层层网上,返回给用户。
设备驱动程序、中断处理程序会直接和硬件打交道。
用户首先会发出I/O请求由上至下,接着硬件进行I/O应答由下之上。
要对LUT逻辑设备表有大概的印象。
输入/输出应用程序接口
提出疑问:对于I/O设备可能由多种不同的读取单位情况,用户层应用程序无法用一个统一的系统调用接口来完成所有类型的设备I/,所以设备独立性软件这一层需要对上层的应用程序提供若干种类型的程序接口。
由于所调用的系统接口是不同的,分别是:字符型设备接口块、设备接口和网络设备的接口。
字符型设备接口
:get/put系统调用,向字符设备读/写一个字符。
块设备接口
:
对于字符、块设备是否使用地址参数原因:对于给上层提供这些不同类型的接口,实际是依据这种类型的设备特性来定义的,字符型设备没有地址的概念,所以get和put就不需要提供地址这个参数,对于块设备则是由地址的概念,所以需要提供一个地址参数。
网络设备接口
:又称"网络套接字socket接口"。
主机2P4进程首先使用socket套接字来创建一个网络套接字(本质就是申请一片内核空间,这边空间可以接收与发送数据),此时socket套接字会给进程返回一个描述符(指向套接字的一个指针)
接着需要使用bind来将这个套接字绑定到本地的某个端口,例如6666端口。
此时主机1P1进程也通过socket系统调用创建一个套接字对象,同时也使用bind来指明本机的端口。
此时两个主机的进程都有各自的套接字,同时确定了各自的一个数据收发端口号。此时就可以使用connect系统调用完成本机的套接字连接到另一台机器上。
此时主机1的P1进程发起connet系统调用,指明对方的ip地址以及对应的端口号:
此时若是想要发送数据包,那么P1首先在自己用户区准备好这个数据包,接着使用write系统调用,会往fd所指向的这个套接字当中写入黄色的这些数据,独立性设备软件层接收到write系统调用后,会把用户进程准备好的这一块数据复制到内核区,也就是套接字所对应的缓冲区。
接下来这一层会调用网络控制器的驱动程序(网卡)来处理这片数据,那这个驱动程序会负责把准备好的数据给它输出到网络设备上,此时网络控制器就可以把数据包发送到网络上了。
此时主机2中的网络控制器会收到发送来的数据包,接着网路控制器会向主机发送一个中断信号,此时中断信号处理程序会调用网络控制器,使用驱动程序来把网络控制器里边收到的这些数据搬到内核的缓冲区里。由于网络包指明了目标的端口6666,此时会将数据复制到6666端口的这片内核缓冲区当中。
若是主机2的P3进程要接受一个网络数据包,此时就只需要使用read系统调用指明fd所指的套接字对象当中读出一个数据包。那么系统调用的结果就是设备独立性软件会从缓冲区里边把数据给它复制到用户进程的这个用户区当中, 此时P3就可以使用者块数据了。
套接字与套接字之间是点对点的,这种连接的建立每一个套接字都会绑定一个本机的端口,此时我们通过主机的IP地址+端口可以连接到世界上任何一个套接字对象。
如何区别不同的数据包要放入的缓冲区?
阻塞I/O
:应用程序发出I/O系统调用,进程需要转为阻塞态等待。
非阻塞I/O
:应用程序发出I/O系统调用,系统调用可迅速返回,进程无需阻塞等待。
由于同类产品是不同公司开发的,那么对于驱动程序接口并不是同一种规范,如何解决?
统一标准的设备驱动程序接口:操作系统规定好设备驱动程序的接口标准,各厂商必须按照要求开发设备驱动程序。若是某个驱动程序想要在我这个操作系统上使用,那么必须按照我的规范标准来,例如read函数的名称、参数要和我给的规范保持一致!
不同的操作系统,对设备驱动程序接口的标准各不相同,那么设备厂商必须根据操作系统的接口要求,开发相应的设备驱动程序,设备才能够被使用。
I/O系统(I/O子系统):属于操作系统的内核部分,主要包含设备独立性软件、设备驱动程序、中断处理程序。
用户层软件
:假脱机技术(SPOOLing技术)。
设备独立性软件
:I/O调度、设备保护、设备分配与回收、缓冲区管理(即缓冲与高速缓存)。
对于假脱机技术实际本来是在用户层软件当中实现的,在考纲中将它们归为I/O核心子系统要实现的功能。
假脱机技术实际上是使用软件实现的。
手工操作阶段:主机直接从I/O设备获得数据,由于设备速度慢,主机速度很快,人机速度矛盾很明显,主机要浪费很多时间来等待设备。【输入、输出都是使用的纸带机,速度特别慢】
批处理阶段引入了脱机输入/输出技术:使用磁带完成
首先先试用纸带机将自己的程序数据输入到磁带中,输入的过程使用一条外围控制机实现,之后CPU可以直接从磁带中读取想要的输入数据,很大的缓解了这种速度的矛盾。同样主机之后可以将数据输出到磁带上,之后还是由外围控制机依次输出到慢速磁带机上。
好处:由于磁带的速度比纸带机块很多,CPU在输入的时候可以节省很多等待输出的完成时间。这样的话就大大提升了CPU的利用率。
为什么称为"脱机"技术呢?
基于脱机技术的思想,发明了所谓的假脱机技术:
“假脱机技术
”,又称"SPOOLing技术
",是使用软件的方式模拟脱机技术,SPOOLing系统的组成如下:
假脱机技术
:输入井、输出井
系统会在磁盘上开启两个存储区域:输入井、输出井。
输入井
:模拟脱机输入时的磁带,用于收容I/O设备输入的数据。输出井
:模拟脱机输出时的磁带,用于收容用户进程输出的数据。相对应批处理阶段的输入井、输出井,实际就是对应的磁带:
假脱机技术
:输入进程、输出进程
其中外围控制机也是一个实现脱机技术的很重要部件,外围控制机是由一个输入进程和一个输出进程实现的。
输入进程
:来实现的输入进程就是模拟脱机。输出进程
:是模拟脱机输出时的外围控制机。这个输入进程与输出进程肯定需要和用户进程并发的执行才可以完成,这种模拟脱机输入和脱机输出的过程,因此SPOOLing技术
,必须要有多道程序技术的支持,系统会建立"输入进程"和输出进程。
假脱机技术
:输入/输出缓冲区
实际对于输入进程、输出进程相对于就是批处理阶段的外围控制机:
实际在内存当中会开启两个缓冲区,一个是输入缓冲区,另一个是输出缓冲区。它们的主要作用就是在模拟脱机输入,模拟脱机输出作用,作为一个数据的中转站。
输入缓冲区
:在输入进程的控制下,"输入缓冲区"用于暂存输入设备输入的数据,之后再转存到输入井当中。输出缓冲区
:在输出进程的控制下,"输出缓冲区"用于暂存从输出井送来的数据,之后再传送到输出设备上。注意:输入缓冲区和输出缓冲区是在内存中的缓冲区。
首先了解一下独占式设备、共享设备:
独占式设备
:只允许各个进程串行使用的设备,一段时间内只能满足一个进程的请求。共享设备
:允许多个进程"同时"使用的设备(宏观上同时使用,微观上可能是交替使用)。可以同时满足多个进程的使用请求。对于打印机这种设备就是属于独占式设备,不过我们可以使用SPOOLing技术
来将其改造为"共享设备"。
独占式例子:若是进程1正在使用打印机,则进程2请求使用打印机时,必然会阻塞等待。
那么如何将打印机实现为共享打印机呢?
当多个用户进程提出输出打印的请求时,系统会答应它们的请求,但是并不是真正把打印机分配给他们,而是由假脱机管理进程为每个进程做两件事。
1、在磁盘输出井中为会进程申请一个空闲缓冲区(这个缓冲区是在磁盘上的),并将要打印的数据送入其中。
2、为用户进程申请一张空白的打印请求表,并将用户的打印请求填入表中(其实就是用来说明用户的打印机数据存放位置信息的),再将该表挂到假脱机文件队列上。
一旦打印机空闲,输出进程会从文件队列的队头取出一张打印请求表,并根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印,通过这种方式来依次处理全部的打印任务。
最终效果:虽然系统之后一台打印机,但每个进程在提出打印请求时,系统都会为在输出井中为其分配一个存储区(相当于分配了一个逻辑设备),让每个用户进程都觉的自己在独占一台打印机,从而实现对打印机的共享。
设备的固有属性三种:独占设备、共享设备、虚拟设备。
独占设备
:一个时间段只能够分配给一个进程(如打印机)。共享设备
:可同时分配给多个进程使用(如磁盘),实际上各进程往往是宏观上同时共享使用设备,而微观上交替执行。虚拟设备
:采用SPOOLing技术将独占设备改造成虚拟的共享设备,可同时分配给多个进程使用。(如SPOOLing技术实现的共享打印机)设备的分配算法:先来先服务、优先级高者优先、短任务优先。
设备分配中的安全性:从进程运行的安全性上来考虑,设备分配有两种方式
方式一:安全分配方式:进程发出I/O请求后,系统为其分配I/O设备,进程可以继续执行,之后还可以发出新的I/O请求,只有某个I/O请求得不到满足时才将进程阻塞。
方式二:不安全分配方式:进程发出I/O请求后,系统为其分配I/O设备,进程可以继续执行,之后还可以发出新的I/O请求。只有某个I/O请求得不到满足时才会将进程阻塞。
静态分配
:进程运行前为其分配全部所需资源(没有全部分配就无法运行),运行结束后归还资源。【破坏了"请求和保持"条件,不会发生死锁】
动态分配
:进程运行过程中动态申请设备资源,并不是一开始就获取到资源。
设备、控制器、通道之间的关系(树形关系):
其中一个通道可以控制多个设备控制器,每个设备控制器可以控制多个设备。
数据结构需要表示出这种从属的关系:设备控制表DCT、控制器控制表(COCT)、通道控制表(CHCT)、系统设备表(SDT)。
设备控制表(DCT)
包含的属性有:设备类型、设备标识符、设备状态、指向控制器表的指针、重复执行次数或时间、设备队列的队首指针。
属性详细介绍如下:
设备类型
:如打印机/扫描仪/键盘。
设备标识符
:即物理设备名,系统中的每个设备的物理设备名唯一。
设备状态
:忙碌/空闲/故障…
指向控制器表的指针
:每个设备由一个控制器控制,该指针可找到相应控制器的信息。
重复执行次数时间
:主要是用于记录失败了几次。只有当重复执行多次I/O操作后仍然不成功,才认为此次I/O失败。
设备队列的队首指针
:指向正在等待该设备的进程队列(由进程PCB组成队列)。
注:“进程管理"章节中曾经提到过"系统会根据阻塞原因不同,将进程PCB挂在到不同的阻塞队列当中去”。
控制器控制表(COCT)
:每个设备控制器都会对应一张COCT。操作系统根据COCT的信息对控制器进行操作和管理。
控制器标识符
:各个控制器的唯一ID。控制器状态
:忙碌/空闲/故障…指向通道表的指针
:每个控制器由一个通道控制,该指针可找到相应通道的信息。控制器队列的队首指针、控制器队列的队尾指针
:指向正在等待该控制器的进程队列(由进程PCB组成队列)。通道控制表(CHCT)
:每个通道都会对应一张CHCT。操作系统根据CHCT的信息对通道进行操作和管理。
若是通道暂时不能为一个进程该服务,那么进程依然需要等待这个通道的服务。最后两个字段是指向等待这个通道的进程队列。
系统设备表(SDT)
:记录了系统中全部设备的情况,每个设备对应一个表目。
在这个表中包含多条设备,每条设备记录中都包含了设备情况,各个字段如下信息:
简洁描述如下:
详细步骤如下:
1、根据设备名来从【系统设备表】中找到匹配的表目。
2、通过【系统设备表中的DCT(设备控制表)地址】找到【设备控制器】后,根据其中的设备状态来判断是否空闲,若是设备空闲可以将设备分配给进程。若是此时忙碌,那么就需要将该进程挂到设备队列的阻塞等待队列中。一直到设备空心啊,将设备分配给该进程之后,才会将这个进程重新唤醒。
3、根据【设备控制表DCT中的指向控制器表指针】找到【控制器表】,此时会检查控制器是否空闲,若是空闲,此时将控制器分配给进程,若是忙碌需要将进程放到控制器的阻塞队列当中。
4、根据【控制器表中通道指针】找到通道控制表CHCT,若是通道空闲将其分配给进程,此时通道忙碌的话,就需要把进程挂到通道的阻塞队列中。
注意:只有当设备、控制器、通道三者都成功之后,这次设备分配才算成功,之后可以启动I/O设备进行数据传送。
设备分配的缺点;
①用户编程时必须使用"物理设备名",底层细节对用户不透明,不方便编程。
②若换下一个物理设备,则程序无法运行。
③若进程请求的物理设备目前正在忙碌,此时系统中还有其他同类型空闲的设备,进程也需要进行阻塞等待。
逻辑设备表(LUT)
:建立了逻辑设备名与物理设备名之间的映射关系。
某用户进程第一次使用设备名时使用逻辑设备名向操作系统发出请求,操作系统根据用户进程指定的设备类型(逻辑设备名)查找系统设备表,找到一个空闲设备分配给进程,并在LUT中增加相应表项。
逻辑设备表的设置方式:
改进方法:建立逻辑设备与物理设备名的映射机制,用户编程时只需要提供逻辑设备名。
缓冲区
:是一个存储区域,可以由专门的硬件寄存器组成,也可以利用内存作为缓冲区。
对于设备独立性软件的缓冲区指的是内存作为缓冲区。
一般情况下,更多的是采用内存作为缓冲区,本节内容也主要是采用内存作为缓冲区来展开。
作用1:缓和CPUI与I/O设备之间速度不匹配的矛盾。
CPU—>缓冲区:CPU可以将输出的数据快速的放入到缓冲区后,即可做其他事情。
I/O设备—>缓冲区:慢速的I/O设备可以慢慢从缓冲区中取走数据。
通过这种方式就可以解决之间速度不匹配的矛盾。
作用2:减少对CPU的中断频率,放宽对CPU中断相应时间的限制。
若是不采用缓冲区的话,那么CPU与I/O设备本身一点是速度不匹配,再者就是每输出一定单位的数据,I/O设备就需要向CPU发出中断信号,对于中断信号是需要一定时间开销的,因此CPU频繁处理这些中断会降低系统的性能。
下面是不采用缓冲区的图示:
作用3:解决数据粒度不匹配的问题。
作用4:提供CPU与I/O设备之间的并行性。
假设某用户进程请求某种块设备读入若干块的数据。
若是采用单缓冲的策略,操作系统会在主存中为其分配一个缓冲区【若是题目没有特别说明,一个缓冲区的大小就是一个块】
注意:
描述一个缓冲区的过程:
①首先系统在主存中为该用户进程分配了一块大小的缓冲区,
②此时该块设备会产生一块大小的数据,把它输入到这个缓冲区当中,此时所耗费的时间为t。
③此时该数据需要传送到用户进程的工作区当中(读入内存),才可以被用户进程所处理,默认用户进程的工作区可以放的下这一块数据,此时会耗费时间为m来将缓冲区当中的数据传送到用户进程的工作区里。
④之后用户进程可以对这一块数据进行处理,这里假设计算处理的时间为c,当处理完成之后,用户进程的工作区后就可以腾空了。
接下来根据上面假设的时间来计算每处理一块数据平均需要多长时间?
情况1:假设初始状态为工作区满,缓冲区空,T>C
由于C时间短,那么我们先来执行C,由于初始状态工作区满,那么我们需要耗费C时间来进行处理,与此同时块设备也可以并行执行输入操作时长为T。
注意:由于缓冲区的规则,只有缓冲区填满之后才能够执行传输操作,所以必须等待T时间结束之后才能够进行传送操作执行M时间。
那么之后的执行操作基本都是一致的,每次都是执行T+M时间,那么平均用时即为T+M:
情况2:假设初始状态为工作区满,缓冲区空,T
此时我们可以先执行输入操作花费T时间,对应CPU处理用户进程的工作区也需要C时间,两者可以并行的完成。
由于T时间短,所以输入操作会先执行完,此时缓冲区已满,但是注意此时还不能够执行传送操作,因为在用户进程的工作区里数据还没有被处理完,此时需要等待处理C全部完成之后,才可以进行传送操作,对应的时序图如下图所示:
那么之后的操作同理,所以平均用时为:C+M
若是两台机器配置双缓冲区:
若是采用双缓冲区的结构,那么两台主机可以同时往自己的发送缓冲区当中,冲入自己想要发送出去的数据,接下来可以同时往对方接受的缓冲区里冲入数据,此时就能够实现同一时刻双向传输的功能。
双缓冲题目:同样是计算机每处理一块数据平均耗时多少
情况1:假设初始状态为工作区空,其中一个缓冲区满,另一个缓冲区空,假设T>C+M
我们可以执行缓冲区1->工作区2
传送(M),与此同时可以并行完成块设备—>内存的输入
(T),在这个过程里若是传送操作完成可以立马开始执行处理©操作,所以最终的时序图如下图所示:
当一次数据传输完毕之后,此时只有当T输入完成之后,我们的缓冲区才会有填满一块数据,所以我们需要再T执行完之后才能够执行传送(M),后面的流程与第一个流程类似:
那么此时处理一块数据平均用时 = T
时间。
情况2:假设初始状态为工作区空,其中一个缓冲区满,另一个缓冲区空,假设T
同样对于缓冲区1—>工作区
与 块设备—>缓冲区2
可以并行执行,对于对于处理操作实际可以连带着在传送(M)完成之后执行,那么第一轮操作如下图所示:
图中可以看到处理©操作阶段,我们是无法将缓冲区1或者2中的数据来传输到工作区的,因为当前工作区并没有被处理完,所以只能够等待处理©结束之后才能够继续完成传送(M)操作。
此时当T执行完成之后,可以继续完成 设备—>缓冲区1 中写入数据,在处理©没有执行完的过程中不能够执行传送的操作,此时可以发现之后的第二次、第三次它们就不再有规律,如下图所示:
但是根据图示还是能够很清晰的看到每一轮花费的时间都是M+C
,这个也就是平均时间。
结论:采用双缓冲策略,无论是T>m+c
还是T
Max(T,C+M)
。
对于单/双缓冲不仅仅是在主机和设备之间的数据传送当中,也可使用在两台主机通信时,也可以采用这种缓冲的策略来用于数据的接收与发送。
若是单缓冲: 只有当A机缓冲区满了之后,才能够向B机缓冲区发送数据。那么对于B机缓冲区满了之后才能够被取走,并且当B机缓冲区为空时才能够向A机缓冲区发送数据。
显然:若是两个相互通信的机器只设置单缓冲区,在任一时刻只能够实现数据的单向传输【这个的主要原因是因为缓冲区的特性决定的】。
对于单/双缓冲区我们需要计算处理一块数据的平均时间,对于循环缓冲区只需要了解大致原理。
循环缓冲区
:将多个大小相等的缓冲区链接成一个循环队列。
下图是一个循环队列,其中橙色表示已充满数据的缓冲区,绿色表示空缓冲区:
缓冲池由一系列的缓冲区组成。
缓冲池
:由系统中共用的缓冲区组成。
缓冲池中的缓冲区按使用状况可以分为:空缓冲队列、装满输入数据的缓冲队列(输入队列)、装满输出数据的缓冲队列(输出队列)。
与此同时,一个缓冲区可以实际运行中可以扮演不同的功能,针对于这个扮演不同功能设置了四种工作缓冲区:
hin
)。sin
)。hout
)。sout
)。四个不同的场景使用到上面四个不同的功能角色。
过程:从空缓冲队列中取出一块作为收容输入数据的工作缓冲区(hin)。充满数据后将缓冲区挂到输入队列队尾。
过程:从输入队列中取得一块充满输入数据的缓冲区作为"提取输入数据的工作缓冲区(sin)"。缓冲区读空后挂到空缓冲区队列中。
过程:从空缓冲区队列中取出一块作为"收容输出数据的工作缓冲区(hout)"。数据充满后将缓冲区挂到输出队列队尾。
过程:从输出队列中取得一块充满输出数据的缓冲区作为"提取输出数据的工作缓冲区(sout)"。缓冲区读空后挂到空缓冲区队列。
上面的各个场景就是举例了从外设输入数据到缓冲区,用户进程读取输入的数据,用户进程将结果输出到缓冲区以及最后的一个取得输出队列中的缓冲区提取数据,左边部分对于收容我觉得就是外设去进行输入输出,对于右边则是用户进程输入、输出数据,实际对于用户进程与外设实际上是实现的双向传输。
磁盘的表面是由一些磁性物质组成,可以用这些磁性物质来记录二进制数据。
磁盘的盘面会被划分成一个个磁道,这样的一个"圈"就是一个磁道。一个磁道又被划分为一个个扇区,每个扇区就是"磁盘块",各个扇区存放的数据量相同(如1KB)。
在磁盘的中间有一个马达,当马达转动的时候,就可以带动整个磁盘的转动。
我们可以对扇区进行编号,0号扇区、1号扇区、2号扇区、3号扇区…,由于每一个扇区中存放的数据量都是相同的,那么最内侧的这个扇区,它的面积是最小的,但是它所存储的数据量又和其他的这些扇区又相同,因此最内存的扇区数据密度最大。
需要把"磁头"移动到想要读/写的扇区所在的磁道,接着磁盘会跟着马达转动起来,让目标扇区从磁头下面划过,才能完成对扇区的读/写操作。
举例:若是想要读取橙色圈的数据,那么我们可以将磁头移动到橙色圈位置,接着马达带动旋转滑动即可。
事实上磁盘当中有很多个盘面,这样的盘面垒起来如下,每一个盘面上都会有一个磁头接着磁头会由磁头臂统一的带动往里往外移动:
注意点:
①一个盘片可能对应两个盘面,也就是正面是一个盘面,背面还可以是另一个盘面。
②所有的这些磁头都是统一的,连在同一个磁臂上的,因此所有磁头只能"共进退"。(例如:一个磁头往里移动时,那么其他磁头肯定也必须跟着往里移动)
③所有在这些盘面当中相对位置相同的这些磁道组成了柱面。例如在图中所有黄色的磁道。
途中所有黄色的磁道在各个盘面上位置都是相同的,所以由这些磁道组成了一个柱面,其实磁盘的物理地址可以用这样的三元来表示:(柱面号,盘面号,扇区号)
的地址形式。
根据该三元组来实现读取一个"块"步骤:
活动头磁盘
:磁头可以移动,磁臂可以来回伸缩来带动磁头定位磁道。每个盘面有一个磁头。
固定头磁盘
:磁头不可以移动,这种磁盘每个磁道有一个磁头。
根据盘片是否可以更换来分为:可换盘磁盘、固定盘磁盘
可换盘磁盘
:盘片可以更换。
固定盘磁盘
:盘片不可更换。
寻找时间(寻道时间)Ts:在读/写数据前,将磁头移动到指定磁道所花的时间。
包含两个部分时间:
①启动磁头臂需要时间,假设耗时s。
②5移动磁头也是需要时间。假设磁头允许移动,每跨域一个磁道耗时为m,总共需要跨越n条磁道,则:
寻道时间计算:Ts = s + m * n。
延迟时间TR:通过旋转磁盘,使磁头定位到目标扇区所需要的时间。设磁盘转速为r(单位:转/秒,或 转/分),则平均所需的延迟时间计算公式:Tn = (1/2) * (1/r) = 1/2r
传输时间Tt:从磁盘读出或向磁盘写入数据所经历的时间。假设磁盘转速为r,此次读/写的字节数为b,每个磁道上的字节数为N,则最终式子如下:
传输时间计算公式为:Tt = (1 / r) * (b / N) = b / (rN)
最终总的存取时间为:Ta = Ts + 1/2r + b/(rN)。
结论:延迟时间和传输时间都与磁盘转速相关,且为线性相关,而转速是硬件的固有属性,因此操作系统也无法优化延迟时间
和传输时间
。
但是寻道时间
是可以进行优化的,具体寻道时间是根据操作系统采用的磁盘调度算法所影响的。
先来先服务算法(FCFS)
:根据进程请求访问磁盘的先后顺序进行调度。
实际举例:
描述:假设磁头的初始位置是100号磁道,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184。
我们首先按照磁道的前后顺序进行排序(目的是更好看出之间顺序,排序的过程不算在算法中,之后算法不再包含这一步):
流程:接着我们按照FCFS的规则,按照请求到达的顺序,磁头需要依次移动到55、58、39、18、90、160、150、38、184,实际就是一开始题目给出的依次顺序,最终移动的顺序如下图所示:
最终计算为:45+3+19+21+72+70+10+112+146 = 498 个磁道。
请求数量为9,那么响应一个请求平均需要移动磁道数(平均寻找长度):498 / 9 = 55.3 个磁道。
优点:公平,如果请求访问的磁道比较集中的话,那么算法性能还是可以的。
缺点:如果有大量进程竞争使用磁盘,请求访问的磁道很分散,那么FCFS在性能上很差,寻道时间长。
最短寻找时间优先(SSTF)
:该算法会优先处理的磁道是与当前磁头最近的磁道。可以保证每次的寻道时间最短,但是并不能保证总的寻道时间最短。
举例:
描述:假设磁头的初始位置是100号磁道,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道。
初始访问的磁道如下图为:
流程:从100开始出发,首先找离最近的磁道就是90,接着还是找最近的,之后依旧是这个策略58、55、39、38、18,后面才是150、160、184。
磁头总共移动磁道数:(100-18) + (184-18) = 248 个磁道。
平均寻找长度(响应一个请求平均需要移动):248 / 9 = 27.5 个磁道
优点:性能比较好,平均寻找时间短。
缺点:可能会产生"饥饿"现象。
饥饿现象出现案例:若是在处理完18号磁道时本应该对应上图要访问150号,但此时突然又来了个访问38号磁道,此时由于38号磁道更近就会先去访问,若是此后陆陆续续来了一些相近的磁道,那么对于早来临的相对较远的磁道如150、160、184,这些磁道就会出现饥饿情况迟迟不会被访问到永远得不到满足,从而产生了"饥饿"现象。
产生饥饿的原因:磁头在一个小区域内来回来去的移动,从而导致举例较远的磁道长时间无法被访问。
对于这个问题此时出现了扫描算法
。
对于最短寻找时间优先(SSTF)
算法会产生饥饿的原因在于:磁头有可能在一个小区域内来回来去地移动。为了防止这个问题,此时可以规定:
扫描算法(SCAN)
:只有磁头移动到最外侧磁道,才能够往内移动,移动到最内侧磁道的时候才能往外移动。对于磁头移动的方式很像电梯,因此也叫做电梯算法
。
核心:只有到了最边上的磁道才能改变磁头的移动方向。
举例:
描述:假设某磁盘的磁道为0-200号,磁头的初始位置是100号磁道,且此时磁头正在往磁道号增大的方向移动,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道。
流程:磁头首相往右边移动首先处理150磁道,接着再往右处理160磁道,之后同样如此,不够需要注意的是该算法要求磁头必须移动到最外侧的磁道才开始往内移动,虽然184号磁道的右边没有需要请求的磁道编号,此时依旧会向右移动直到移动到最外侧的200磁道才开始往内移动。此时会移动到90磁道为止开始进行读取,接着依次是58、55、39、38、18。
磁头总共移动磁道数:(200-100) + (200-18) = 282 个磁道。
平均寻找长度(响应一个请求平均需要移动):282 / 9 = 31.3 个磁道
优点:性能较好,平均寻道时间较短,不会产生饥饿现象。
缺点:
①只有到达最边上的磁道才能够改变磁头移动方向,事实上,处理了184号磁道的访问请求之后就不需要再往右移动磁头了。
②SCAN算法对各个位置的磁道响应频率不平均。
总结:对于靠近边上的磁道相对来说更好被重复访问到,对于中间的磁道当访问了一次又来临,只能够等待扫描到最边上后才能够返回过来扫描。
问题描述:扫描算法(SCAN)中,只有到达最边上的磁道时才能够改变磁头移动方向,事实上,处理了184号磁道的访问请求之后就不需要再往右移动磁头了。
Look调度算法
:为了解决这个问题,如果在磁头移动方向上没有别的请求了,就可以立即改变磁头移动方向。
举例子:
描述:假设磁盘的磁道为0-200号,磁头初始位置为100号磁道,且此时磁头正在往磁道号增大的方向移动,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184。
流程:磁头同样是会向右移动,与扫描算法(SCAN)一样不断地向右移动,不过不同的是在访问了184号磁道后,由于右边没有需要请求的磁道号,那么此时就会直接改变磁头的移动方向,开始处理90、58、55、39等等,如下图所示:
磁头总共移动磁道数:(184-100) + (184-18) = 250 个磁道。
平均寻找长度(响应一个请求平均需要移动):250 / 9 = 27.5 个磁道
优点:比起SCAN算法,不需要每次移动到最外侧或最内侧才改变磁头方向,使寻道时间进一步缩短。
问题描述:扫描算法(SCAN)中,对于各个位置磁道的响应频率不平均,而C-SCAN算法就是为了解决这个问题。
循环扫描算法(C-SCAN)
:规定只有磁头朝某个特点方向移动时才处理磁道访问请求,而返回时直接快速移动到起始端而不处理任何请求。
描述:假设磁盘的磁道为0-200号,磁头初始位置为100号磁道,且此时磁头正在往磁道号增大的方向移动,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道。
流程:磁头首先会向右边的最近磁道进行服务,依次是150、160、184,注意虽然右边的200并不是请求访问的磁道,但是根据该算法规则只有到了最边上的磁道才能改变磁头移动方向。磁头返回途中不处理任何请求。那么当访问到200后,会直接将磁头移动到0磁道(不会进行任何处理),之后才依次处理18、38、39、55…往后的磁道。
磁头总共移动磁道数:(200-100) + (200-0) + (90 - 0) = 390 个磁道。
平均寻找长度(响应一个请求平均需要移动):390 / 9 = 43.3个磁道
该算法十分平均体现在哪里?
优点:比起SCAN来,对于各个位置磁道的响应频率很平均。
缺点:只有到达最边上的磁道时才能够改变磁头移动方向,事实上,处理了184号磁道的访问请求之后就不需要再往右移动磁头了;并且,磁头返回时其实只需要返回到18号磁道即可,不需要返回到最边缘的磁道,另外比起SCAN算法,平均寻道时间更长。
为了解决C-SCAN算法缺点,提出了C-LOOK调度算法。
C-SCAN算法的主要缺点是只有到达了最边上的磁道才能改变磁头移动方向,并且磁头返回时不许奥返回最边缘的磁道。
C-LOOK调度算法
:就是为了解决这个问题,如果磁头移动的方向已经没有磁道访问请求了,就可以立即让磁头返回,并且磁头只需要返回到有磁道访问请求的位置即可。
描述:假设磁盘的磁道为0-200号,磁头初始位置为100号磁道,且此时磁头正在往磁道号增大的方向移动,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道。
流程:磁头首先会向右边的最近磁道进行服务,依次是150、160、184,对于右边的200磁道由于并不是需要进行请求读取的,那么此时以后直接掉头移动到左侧的要访问的第一个位置(不做任何处理,对于左边的0虽然是边界但是不需要请求访问的)此时磁头会进行掉头之后才依次处理18、38、39、55…往后的磁道。
磁头总共移动磁道数:(184-100) + (184-18) + (90 - 18) = 322个磁道。
平均寻找长度(响应一个请求平均需要移动):322/ 9 = 35.8个磁道
优点:比起C-SCAN算法,不需要每次都移动到最外侧或最内侧才改变磁头方向,使寻道时间进一步缩短。
评价:与LOOK算法十分类似:若是磁头移动的方向已经没有磁道访问请求了,此时可以让磁头立即返回。
一次磁盘读/写操作所需要的时间:
假设:要连续读取橙色区域的2、3、4扇区:磁头读取一块内容(也就是一个扇区的内容)后,需要一小段时间处理,而盘片又在不停地旋转。因此,如果2号、3号扇区相邻着排列,则读完2号扇区后无法接连不断地读入3号扇区。
我们来看下图,下图时磁头已经读取完2号扇区,还需要一定时间来处理(所以不能在读完2号扇区后就直接读取3号扇区),而磁盘又是不断旋转地,实际磁头还在处理2号扇区的数据,这个处理数据的时间如下图:
那么如何才能够读取3号扇区呢?
结论:磁头读入一个扇区数据后需要一小段时间处理,如果逻辑上相邻的扇区在物理上也相邻,则读入几个连续的逻辑扇区,可能需要很长的"延迟时间"。
核心原因:逻辑上相邻的扇区,物理上也相邻。
解决方案:逻辑上相邻,物理不相邻有一段间隔。
流程:首先要读入的是2号扇区,首先需要转动磁盘,让2号扇区放到这个磁头的下面,接着让这个磁盘继续转动的过程中就可以把2号扇区的数据读入,在读完2号扇区之后,这个磁头需要有一小段时间做中间的准备,在这段时间内,磁头时不能读入任何数据的。
由于采用了交替编号的策略,在三号扇区划过磁头之前,该磁头就做好了下一次读取数据的准备。此时该盘片继续旋转,三号扇区从磁头下面划过,此时磁头也可以顺利的把三号扇区里的数据给读进来。
效果:采用了交替编号这种策略,可以大幅度的减小延迟时间。即让逻辑上相邻的扇区在物理上有一定的间隔,可以使读取连续的逻辑扇区所需要的延迟时间更小。
(盘面号,柱面号,扇区号)的二进制设计
假设某磁盘有8个柱面/磁道(假设最内侧柱面/磁道号为0),4个盘面,8个扇区,各自采用多少位表示呢?
下面仅仅展示的是一个盘面的图示:
读取一圈数据需要旋转的圈数
首先明确一点对于内侧一圈的数据我们实际需要旋转多少圈呢?
解释:根据我们之前3.3.2章节减少延迟时间的方案,我们实际旋转一圈只能够读取0、1、2、3扇区,当旋转第二圈时则读取4、5、6、7扇区。
题目:假设某磁盘有8个柱面/磁道(假设最内侧柱面/磁道号为0),4个盘面,8个扇区,可用3个二进制位来表示柱面,2个二进制位表示盘面,3个二进制位表示扇区。
需求:若是物理结构是(盘面号,柱面号,扇区号),且需要连续读取物理地址(00,000,000)-(00,001,111)的扇区?
其中对于(00,000,000)-(00,000,111)我们实际旋转两周即可。
而对于(00,000,111)- (00,001,000),此时由于中间的是001是转到1号柱面,此时会移动磁头,这个移动磁头的动作,就会有额外的耗费时间!
也就是说若是盘面放到中间,那么在连续读一块区域数据时(中间位置改变数字)就会很容易的出现移动磁头的情况。
题目:假设某磁盘有8个柱面/磁道(假设最内侧柱面/磁道号为0),4个盘面,8个扇区,可用3个二进制位来表示柱面,2个二进制位表示盘面,3个二进制位表示扇区。
需求:若是物理结构是(柱面号,盘面号,扇区号),且需要连续读取物理地址(00,000,000)-(00,001,111)的扇区?
此时同样是读取(00,000,000)-(00,001,111),我们直接快进到关键步骤(00,000,111)- (00,001,000),这个中间的001则是选择1号盘面,此时磁盘会做的操作则是激活1号盘面的磁头。
由于柱面号/磁道号相同,只是盘面号不同,因此不需要移动磁头臂,只能够激活相邻盘面的磁头即可。这个时间比磁头移动的时间少了很多!
区别:
(盘面号,柱面号,扇区号)
,那么执行连续的如000 00 000 - 000 10 111,由于中间的使柱面号,那么就需要去移动磁头,会有额外的耗费时间,关键是这个柱面号在整个二进制中间,是否多的情况会影响到整个磁头移动;(柱面号,盘面号,扇区号)
,只有在01 000 000、10 000 000,这种顶部数字改变的时候才会去让磁头移动,若是如000 10 111,由于此时中间的是盘面号,那么只需要激活相对应的盘面磁头即可开始读取数据,所以比之前的那种设计会更好。解答:读取地址连续的磁盘块时,采用(柱面号,盘面号,扇区号)
的地址结构可以减少磁头移动消耗的时间。
问题:若是将多个盘面相对位置相同,扇区编号也相同,会增加延迟时间。
示例:若是相邻的盘面相对位置相同处扇区编号相同,此时所有的盘面都是一起连轴转的。
首先是读取(000,00,111)这个物理位置的扇区数据,需要旋转两圈:
旋转完第二圈之后,实际还会对第二圈数据处理一小段时间,注意了此时磁头的位置已经移动到了第4号扇区(磁头是同时旋转的多个盘面):
而接下来我们是要读取(000,01,000)扇区的数据,此时会激活1号盘面开始读取数据,可以你会发现当前的磁头已经是在4号扇区的位置(由于处理之前第二圈数据损耗时间影响的),此时若是想要读取0号扇区,那么就需要重新转一圈移动到0号扇区初始位置!!!
此时可以采用一种解决方案:错位命名
解决方案:不同的盘面对应的扇区号并不相同。
例如当前0号盘是从0号扇区初始位置开始,1号扇区则是在7号盘初始位置开始。
此时我们重新回顾下读完两圈之后并且加上处理第二圈的时间,此时1号盘的磁头会旋转到哪里?
可以看到最终加上处理第二圈的时间,此时1号盘面的磁头可以正好移动到0号盘面的位置(物理上进行了错位命名),此时就可以直接读取数据,从而减少了延迟时间。
磁盘的初始化过程:
Step1:进行低级格式化(物理格式化),将磁盘的各个磁道划分为扇区。其中管理扇区所需要的各种数据结构一般存发给在头、尾两个部分,包含扇区校验码(如起偶校验、CRC循环冗余校验码,校验码用于校验扇区中的数据是否发生了错误)。
Step2:将磁盘分区,每个分区由若干个柱面组成(即分为我们熟悉的C盘、D盘、E盘)。
Step3:进行逻辑格式化,创建文件系统。包括创建文件系统的根目录、初始化存储空间管理所用的数据结构,例如位示图、空闲分区表。
注意:扇区的划分是在进行低级格式化(Step1步骤)的时候进行的。
在磁盘完成了物理格式化,还有磁盘分区、逻辑格式化之后,就可以将操作系统相关数据写到磁盘当中,这也是自己装操作系统的一个过程,在计算机开机启动的时候,需要进行一系列的初始化工作,包括初始化CPU、初始化内存、还有初始化寄存器之类的一些应急那部件。
这个初始化的过程需要执行所谓的初始化程序,也叫做自举程序。在计算机开机的时候,会读取ROM当中的这些程序,并且执行这些程序来完成初始化的工作。
引导块
:在计算机开机启动的时候,需要进行一系列的初始化工作,这些初始化工作是通过执行初始化程序(自举程序)完成的。
自举程序通常是存放在ROM当中,也就是只读存储器当中,而ROM中的数据是在出厂的时候就已经写到了ROM当中,之后是无法修改的。
注意:ROM一般是出厂时候就集成到主板上的。
此时有一个问题:初始化程序(自举)程序放在ROM中存在着一些问题,若是需要更新自举程序,那么会十分不方便,因为ROM中的数据无法更改,如何解决?
解决方案:实际在ROM中只存放很小的"自举装入程序"。完整的自举程序会放在磁盘的启动块(即引导块/启动分区)上,启动块位于磁盘的固定位置。
执行流程:当计算机开机的时候,首先会执行ROM中的自举装入程序,在执行自举装入程序的过程中,CPU就可以找到引导块,接着将完整的"自举程序"读入内存,即可完成初始化。
好处:自举程序的更新会变得十分方便。
**启动磁盘(系统磁盘,C:盘):**拥有启动分区(引导块启动块)的磁盘。
坏块
:指的是坏了,无法正常使用的扇区就是"坏块"。属于硬件故障,操作系统是无法修复的,应该将坏块标记出来,以免错误地使用到它。对于坏块不再分配给任何一个文件。
对于坏块的管理一般有两种方式:FAT表标明、维护坏块链表。
策略:对于简单的磁盘,可以在逻辑格式化时(建立文件系统时)对整个磁盘进行坏块检查,指明哪些扇区是坏扇区,比如:在FAT表上标明。
是否对操作系统透明:对操作系统不透明。
策略:对于复杂的磁盘,磁盘控制器会维护一个坏块链表。在磁盘出厂前进行低级格式化(物理格式化)时就将快坏链进行初始化。
磁盘控制器
:指的是磁盘设备内部的一个硬件部件。对于一些坏块,此时会保留一些"备用扇区",用于替换坏块。这种方案称为扇区备用。
是否对操作系统透明:对操作系统透明。
新增大纲:
选择题考查的特性列举在了下面思维导图中:
机械硬盘存储数据都是基于小盘面上的磁性物质来记录二进制0与1;固态硬盘存储介质基于闪存技术(u盘同样也是)。
通过IO总线来发送逻辑地址,接着通过闪存翻译层来映射到对应的物理地址,闪存翻译层做的是地址变换的工作。
接着深挖闪存芯片内部的结构,一个闪存芯片由若干个数据块组成,一个块大小在16KB-512KB。
每一个块可以拆解为一个个页,每个页大小为512B-4KB。
注意:系统对于固态硬盘的读写是以页为单位的。每次读/写一个页。
针对其中一个特性:固态硬盘会以块的单位擦除,擦干净的块,其中的每页都可以写一次,读无限次。
若是在一个块中先写了几个页,那么再去修改那几个页是不被允许的,除非去把整一块擦除才能够重新写。
若是我只想重写一页呢,难道要把整一块来进行擦除吗?实际上固态硬盘会将指定的除了那一页的其他页写入到其他块中也就是先复制到另一块中,然后将新的一页页写到另一块中,接着将原先的那一块擦除即可。
由于这个特性导致固态硬盘读快,写慢。
关于机械硬盘与固态硬盘定位的区别:固态硬盘是通过电路迅速定位;机械硬盘则通过移动磁臂旋转。
固态硬盘的缺点:若是频繁的在一个块上进行擦写重写,那么会导致坏掉。
根据这个缺点,就有了解决方案:磨损均衡技术。也就是想办法将擦除平均的分布在各个块上,用于提升使用寿命。针对于读多写少的数据块则可以将其数据迁移到比较老的块上。主要原因是读多写少,那么对于擦除的需求就很少。
整理者:长路 时间:2023.7.19-22