操作系统二轮复习(IO管理)

IO控制器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

I/O控制方式

程序直接控制方式

在这里插入图片描述
在这里插入图片描述

中断驱动方式

在这里插入图片描述
在这里插入图片描述

DMA 方式(直接存储器存取)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通道控制方式

在这里插入图片描述
在这里插入图片描述

表格总结

在这里插入图片描述

I/O软件的层次结构

在这里插入图片描述

设备独立性软件=系统调用处理程序

在这里插入图片描述

设备驱动程序:主要负责对硬件设备的具体控制,将上层发出的一系列命令(如read/write)转化成特定设备“能听得懂”的一系列操作。包括设置设备寄存器;检查设备状态等

I/O核心子系统

在这里插入图片描述
在这里插入图片描述

假脱机技术( SPOOLing 技术)

在这里插入图片描述

要实现SPOOLing 技术,必须要有多道程序技术的支持。系统会建立 “输入进程”和 “输出进程”

在这里插入图片描述
在这里插入图片描述

设备的分配与回收

在这里插入图片描述

设备控制表(DCT)

在这里插入图片描述

控制器控制表(COCT)

在这里插入图片描述

通道控制表(CHCT)

在这里插入图片描述

系统设备表(SDT)

在这里插入图片描述

总结

在这里插入图片描述

缓冲区管理

在这里插入图片描述

输入/输出应用程序接口

在这里插入图片描述
在这里插入图片描述

首先来看什么是输入输出应用程序接口。很简单,结合这个图来理解,IO软件分为多个层次。上层的用户应用程序需要通过系统调用的方式来请求使用底层的某一种 lO 设备,那我们知道 I O 设备的种类、特性非常的多样化,所以上层的应用程序很难通过一个统一的系统调用接口来操作所有类型的这些IO设备
比如:像块设备,就是有寻址的概念,一个磁盘可以指定说要读这个磁盘的哪个地址,对吧?这是一个磁盘,那我们可以有一个读写指针,指向磁盘的某一个位置,然后我们每一次可以指定要读几个字节,或者要读多少个kb等等,所以由于块设备他有寻址的,同时这个块设备支持多个字节的读写,因此当我们自己写程序的时候,我们用系统调用的方式,从块设备当中读入数据,
那么我们的这个read系统调用是不是就可以写成首先要指明你要操作的是哪个块设备,对吧?另外,我可以指明我此次要读入几个字节,同时我还可以指明我要从哪儿开始读。因为块设备有地址的概念嘛。那只是对于块设备的读,那你想一下这种读操作的系统调用接口适用于字符型设备吗?显然不适用,因为字符型设备是不可寻址的,
比如说键盘就是最典型的字符型输入设备,每一次我们只能读一个字符,键盘是没有地址的概念的,所以我们在用系统调用。从键盘当中读一个字符的时候,我们可以指明我们要从哪个地址读吗?显然不行,因此可以看到由于底层的设备多种多样。对于各种类型设备的这个访问 IO 读写所需要提供的调用参数也各不相同,因此很显然,我们用户层的应用程序无法用一个统一的系统调用接口来完成所有类型的设备 IO。


分别看一下这三种设备(字符设备、块设备、网络设备)的接口分别有什么特性?

用户层的应用软件如果要使用一个字符型的设备。要对字符型的设备进行读,或者写,那么要采用get或者put这两个系统调用。Get就是从指定的字符设备当中读出一个字符。而put是往指定的这个字符设备当中写一个字符。数据的读写是以字符为单位的,好,这是给字符型设备提供的接口。


接下来快设备的这个系统调用接口,是我们最熟悉的readWrite系统调用,块设备有地址的概念,比如这是一整个磁盘,那么我们可以用seek系统调,用来指定我的这个读写指针要放到磁盘的哪个地址。那放到这个地址之后,我就可以使用read或者write往读写指针所指的这个位置后面读若干个单位的字符,或者写若干个单位的字符。我每次可以读写多个字节,多个字符,同时我也要指名读写的这个地址,这个位置。好,这是块设备的接口。


在这里插入图片描述

我们来看一个大家不熟悉的网络设备的接口。大家经常听说你的电脑里边有一个什么网卡,对吧?那这个网卡就是所谓的网络控制器,就是用于收发网络数据包的。那显然你电脑上的这个网络控制器,它可能会收到很多很多的数据包。而不同的数据包应该丢给不同的应用程,比如说你同时在使用支付宝,也同时在使用微信,那么你的网卡会收到给支付宝的数据包,也会收到需要给微信的数据包,那这些数据包到底应该给哪一个具体的应用程序呢?我们是不是得做一些区分?好,所以为了达成这个目的,网络设备接口又叫网络套接字接口。会向上层的这个应用程序提供socket系统调用,这个系统调用的作用是可以创建一个网络套接字。
这个网络套接字是什么意思?我们一会儿再来解释,那当我们创建这个网络套接字的时候,还需要指明我们要连接的这个网络协议是什么样的协议?比如说是tcp还是udp?需要指明这个传输协议好,有了一个网络套接字之后,就可以使用bind这个系统调用,把套接字绑定到本地的某一个端口上。大家都学过计算机网络,我们知道每一台电脑会有一个各自的IP地址,IP地址定位到了一台电脑,一台主机,如果我们再加上一个端口号,一个端口号,那么这个端口号,就可以映射到计算机当中的某一个应用程序,一会儿我们会用一个实际的例子来进行感受,好,
接下来设备独立性软件还提供了connect这个系统调用。这个系统调用,可以把套接字连接到远程的某一个主机上。那当我们这个网络套接字初始化完毕之后,就可以使用read或者write对网络套接字进行数据的读写了,这么说比较抽象,给大家画了一个图,方便你理解。

左边这是一台主机,右边这是另一台主机,然后他们之间用网络进行连接,每一台主机上可能会同时运行着多个进程,比如说第一台主机就运行了p1和p2两个进程。另外每台主机都会有一个网络控制器,也就是我们熟悉的网卡,用于实现网络数据包的收发。同时每一台主机都会有各自的一个IP地址,那每一个进程都会有自己的这个进程用户空间,同时操作系统内核也会有操作系统内核的这个空间。好,那现在看一下这些用户进程是如何使用网络设备接口,也就是刚才我们提到的这个socket接口来实现网络通信的。

主机2,p3这个进程要进行网络通信,它可以先使用socket系统调,用来创建一个网络套接字。那网络套接字这个翻译,我认为可能不太好理解,你不妨把它简单的理解为就是要申请一片内核存储空间。这片空间会用于接收或者发送数据。,那么socket系统调用会给用户进程返回一个描述符,你可以理解为就是指向套接字的一个指针好呢,有了这个套接字对象之后,我们还需要做一个事情。就是要bind,要把这个套接字绑定到本地的某个端口,比如说我bind。绑定到本地的6666这个端口,那这样主机二的这个套接字就可以等待着被连接。

接下主机1也可以做相同的操作,p1进程通过socket这个系统调用来申请创建一个套接字对象。同时也需要通过bind系统调用来指明这个套接字对象要绑定到本机的什么端口,那我们假设这个端口号是211。好,现在两个主机都有了各自的套接字,同时也确定了各自的一个数据收发的端口号。接下来一步要做的事情,就是使用connect这个系统调用把本机的套接字连接到另一台机器的套接字上,比如说可以让主机1的这个p1进程使用connect系统调用。指明我要把fd所指向的这个套接字连接到这个IP地址的666这个端口这儿。就是把IP地址以及端口号作为参数给写进去,好,那这个系统调用就会使得这两个套接字之间建立起一个连接,如果结合计网来看的话,这个连接属于应用层的一个连接。那他们在传输层可以指定一种呃规定好的协议,比如说可以使用tcp协议,或者可以使用udp协议等等。

现在两个套接字已经建立好了连接,那接下两个主机就可以通过套机。来进行通信了,比如现在p1想给p3发送一个数据包,那么p1首先在自己的用户区准备好这个数据。然后使用write系统调用,指明我要往fd所指向的这个套接字当中写入黄色的这些数据。设备独立性软件接收到write的这个系统调用之后,它就会把用户进程准备好的这一块数据。这块数据给复制到内核区,也就是套接字所对应的这一片缓冲区当中。这一步是设备独立性软件那一层来完成的事情,绿色的这片区,你可以理解为是设备独立性软件管理的一片缓冲区。而现在数据已经放到内核缓冲区里边了,接下来设备独立性软件这层,他会调用网络控制器的驱动程序来处理这片数据,那这个驱动程序会负责把准备好的这一坨数据给他输出到这个网络设备上,接下来网络控制器是不是就可以把这些数据包给发送到网络上了?那么这些数据在网络上的发送,就需要使用到大家在计网里面学过的什么tcp协议,udp协议那系列的东西。

因为我的这个套接字对象是知道我的数据包应该发送到哪个IP地址的哪一个端口,所以这个网络控制器在发送数据包的时候,也可以明确的知道这个数据包应该何去何从,这个数据包一路顺着网线爬到主机2的网络控制器上,那这个网络控制器接收到一个数据包之后,会向主机发出一个中断信号,那主机2的中断处理程序是不是就出来工作了?中断处理程序发现中断信号是来自于这个网络控制器,因此中断处理程序接下来会调用网络这个驱动程序,让驱动程序来把网络控制器里边收到的这些数据给他搬到内核的缓冲区里面呐,因为我们早就知道这个数据应该发送到6666这个端口这儿,所以数据会被复制到6666这个端口所对应的这一片内核缓冲区中。好,现在数据已经一路发到主机2这边了,那接下来p3这个进程,他要接收一个网络数据包,是不是只需要使用read系统调用,指明我要从fd所指的这个套接字对象当中读出一个数据,那么这个系统调用的结果就是设备独立性软件会从缓冲区里边把这一坨数据给他复制到用户进程的这个用户区当中,那这样用户进程p3就可以使用它收到的这一块数据了。

那通过刚才的例子,相信你对网络设备接口已经有了一个比较直观的理解。

用户进程可以使用网络设备相关的系统调用接口来创建一个套接字对象。那套接字和套接字之间,需要进行点对点的这种连接的建立。每一个套接字会绑定一个本机的端口,那么我们通过主机的IP地址,再结合上套接字绑定的这个端口,就可以找到全世界任何一个套接字对象。那两个套接间建立这种点对点的连接,就是通过IP结合端口来实现的。

刚才这个P1进程建立了和p3进程的一个套接字的连接。那这个主机上还有p2进程,对吧?p2进程想要和另一台主机上的另一个套接字建立连接,那p2进程是不是也可以使用socket系统调用?也就是网络设备接口来申请一个新的套接字,同时把申请的这个套接字绑定另一个端口,是不是就ok了?正是因为不同的套接字绑定了不同的端口,因此你的网卡接收到很多数据包之后,才可以根据这个数据包里边指明的端口信息,把这个数据包放到合适的对应的这个套接字对象这儿。
所以你手机同时运行那么多多软件,所有的软件都需要网络通信,但是这些数据包的传输并不会出现任何的失误。这就是设备独立性软件,向应用程序提供的网络设备接口。

阻塞IO和非阻塞IO

在这里插入图片描述

接下来我们来看一下阻塞io和非阻塞io,很简单的两个概念。
阻塞io就是指应用程序发出io相关的这个系统调用之后,需要转为阻塞态,等待io的完成。
比如说要从键盘get读入一个字符,那么只要这个键盘,它输入的动作没有完成。这个进程就得一直等下去。所以我们初学者在写scanf,等待这个键盘的输入的时候,只要你的键盘不输入,你的这个进程,就没有办法继续往下执行。那这就是所谓的阻塞。发出了IO系统调用请求之后,需要阻塞等待。

那相反,非阻塞io就是发出系统调用请求之后,系统调用可以迅速的返回进程,无需阻塞等待。
比如要用write系统调用往磁盘写数据,那这个系统调用可以很快的被处理完。然后迅速的返回到用户进程,让他继续往下执行,即便你的磁盘正在忙碌,也是这样的,也不需要你的用户进程等待。
因为准备的数据是在用户区,而操作系统内核又有内核区。那你发出了write系统调用,想要把这块数据写到磁盘的时候,即便磁盘现在正在忙碌。那设备独立软件内存也会迅速的响应。
你的这个系统调用请求,先把你的这一块数据复制到内核再说,只要这块数复制到内核,那接下来内核慢慢的把这个数据写回磁盘是不是就行了?至于用户进程,只要完成了这个数据复制的过程,我就可以让你继续往下执行了,所以这种类型的系统调用不需要阻塞等待。可以迅速的返回,那这就是非阻塞的IO

设备驱动程序接口

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

接下来看最后一个接口,设备驱动程序的接口。同样从层次结构这个图出发,设备独立性软件需要根据实际操作的设备不同去调用不一样的设备驱动程序,比如逻辑公司和雷蛇公司。生产各自的设备,而这些公司他们需要自己实现自己的驱动程序,比如说对罗技公司的设备进行读操作,那么读操作的这个函数调用就是read后面跟两个参数,而另一个公司的驱动程序,它的接口可能不一样。同样叫read,但是你需要传入三个参数,那这对于设备独立性软件来说是不是就很麻烦?我要调用不同公司编写的驱动程序,我还得修改我的这个函数调用的代码。也就是要频繁的修改操作系统的内核,那这显然不科学,
因此如果每个公司他们开发的这些设备驱动程序向上层暴露的这个接口形状不统一,那么操作系统就很难调用不同设备的这些驱动程序。
因此操作系统会统一一个标准,要求设备的厂商在制作这个驱动程序的时候,按照我规定好的这个统一标准来开发你的驱动程序,比如说我规定任何一个厂商,你想让你的设备在我这个操作系统上正常被支持,被使用,那么你提供的这个read系统调用就必须名字叫read,然后后面有三个参数,而且参数的类型,大小什么的,我都会给你一个统一的标准,那么各个厂商就可以根据操作系统规定的这个标准,去开发专属于这个操作系统的驱动程序。比如说我自己在平时录课的时候,会使用到一块数位板,这也是一个io设备,在他的官网上,你就会看到它有mac系统的一个驱动程序,有Windows系统的一个驱动程序呐,因为不同的操作系统,它对设备驱动程序的接口的标准各不相同,所以这个设备厂商就必须要根据不同操作系统提出的这个标准要求来开发不同的设备驱动程序,只有这样,自己的设备才可以在各种操作系统上被支持,被使用。这就是设备驱动程序接口
驱动程序这一层需要向上层的设备独立性软件提供一个统一标准的接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sparky*

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

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

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

打赏作者

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

抵扣说明:

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

余额充值