我是靠谱客的博主 重要野狼,最近开发中收集的这篇文章主要介绍I/O内核的子系统,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

基本概念

内核提供了许多和I/O有关的服务。像调度、缓冲、高速缓存、假脱机、设备预留以及错误处理是由内核I/O子系统提供的并且是建立在硬件和设备驱动程序结构之上的,I/O子系统还负责保护自己免受错误进程和恶意用户的危害

下面简单的介绍下I/O的调度

其实调度I/O请求就是确定一个合适的顺序来执行这些请求,如果调用的顺序选择的合理,那么调度就能改善系统整体性能,能够在进程之间公平地共享设备的访问,能减少I/O完成所需要的平均等待时间

举个例子,就比如说现在磁盘的磁头在磁盘的开始的位置,三个应用程序向这个磁盘发布阻塞的读调用,应用程序1需要磁盘结束部分的块,应用程序2需要磁盘开始部分的块,应用程序3需要磁盘中间部分的块。操作系统如果按照2、3、1的顺序进行处理,则可以降低磁头所需要移动的距离,但是如果说我使用1、2、3的顺序来调用那肯定效率不高

操作系统可以通过为每个设备维护一个请求队列来实现调度,当一个应用程序执行阻塞I/O系统调用的时候,这个请求就可以加到相应设备的队列上,I/O调度可以重新安排队列顺序来改善系统总体效率和应用程序的平均响应时间

操作系统可以基于一个好的算法来进行平均分配,这样的话就没有应用程序会得到特别不好的服务,我们也可以根据服务优先权给予那些对延迟很敏感的请求。就比如说虚拟子系统的请求会比应用程序的请求有优先权

为了支持异步的I/O,内核需要同时的去跟踪多个I/O请求,所以操作系统就为设备状态表去配备了等待队列。内核会去管理这个表,这个表当中包含了每一个I/O设备的条目,每一个表的条目都表明了设备类型、地址和状态(不工作、空闲或忙)。如果设备在忙于一个请求,那么请求的类型和其他参数就会被保存在该设备相应的表条目当中

下面就是关于设备表的详情以及请求队列

这里写图片描述

I/O子系统改善计算机效率的一种方法就是I/O操作的调度,另一种方法就是使用主存、缓冲、高速缓存和假脱机等

缓冲

缓冲区是用来保存两个设备之间在或者是在设备和应用程序之间所传输数据的内存区域。采用缓存有三个理由。一个就是处理数据流的生产者与消费者的速度差异,比如说从调制解调器中接收到了一个文件,并且保存到硬盘上,调制解调器大约比硬盘慢数千倍。这样的话就可以在内存中创建缓冲区以累积从调制解调器处接收到的字节,如果这个缓冲区满了之后,再去写到磁盘,但这有个问题如果我还有数据呢?还需要写入缓冲区呢?那么我们就需要去第二个缓冲区,第一个缓冲区写入磁盘数据,第二个缓冲区我们去继续累积从调制解调器去接收数据

缓冲区的第二个用途是协调传输数据大小不一致的设备,就比如说在计算机网络当中,缓冲常常用来处理消息的分段和重组,在发送端,一个大消息分成若干小网络包,这些包通过网络传输,接收端将它们放在重组缓冲区内,以生存完整的源数据镜像

缓存的第三个用途是支持应用程序I/O的复制语义,复制语义就是如果某应用程序需要将缓冲区内的数据写入到磁盘当中,它可以调用write()系统,并给出缓冲区的指针和表示所写字节数量的数量的整数,如果在系统调用返回的时候,改变了缓冲区的内容,根据复制语义,操作系统保证要写入磁盘的数据就是write()系统调用时发生的版本,不需要去考虑应用程序缓冲区随后发生的变化。一个简单的方法就是操作系统在write()系统调用返回到应用程序之前就将应用程序换区复制到内核缓冲区当中

高速缓存

高速缓存是可以保留数据副本的高速存储器。高速缓冲区副本的访问要比原数据访问更高效,就比如说正在执行的进程的指令既可以存储在磁盘上,也可以存在物理内存上,还被复制到CPU的二级和一级高速缓存当中

缓存和缓冲的区别就在于缓冲可能是数据的唯一的副本,而根据定义高速缓存只是提供了一个驻留在其他地方的数据在高速存储上的一个副本

假脱机

假脱机就是用来保存设备输出的缓冲区,这些设备通常不能接收交叉的数据流,举个打印机的例子,就是我们每个人共享一台打印机,但是我们都可以使用这个打印机进行打印,会按照一定的顺序来进行,就比如说应用程序先假脱机到一个独立的磁盘文件上,然后当应用程序完成打印之后,假脱机系统将相应的等待打印机打印的假脱机文件进行排队,假脱机系统一次复制一个已排队的假脱机文件到打印机上

错误信息的传递

I/O系统调用通常返回一个位来表示调用状态信息,以此表示成功或者是失败,对于UNIX操作系统来说,一个名为errno的额外整数变量用来表示出错代码,大概有100个表示错误的原因就比如说有参数超过范围,坏指针,文件未打开。有的硬件也可以提供很详细的出错信息,不过现在目前的大多数操作系统并不会将这些信息传递给应用程序,比如说SCSI设备的失败可以通过SCSI协议以三个级别的详细信息来表示

  • 表达一般失败信息的比如硬件出错或者非法请求的sense key
  • 表达失败类型,如错误命令参数或自检失败的additional sense code
  • 表达更加详细的信息,比如哪个命令参数出错或者是哪个硬件子系统自检失败的additional sense code qualifier

很多SCSI设备都会维护一个出错日志信息以便主机查询

I/O保护

为了防止用户执行非法的I/O操作,定义所有的I/O指令为特权指令,也就是说用户不能直接发出I/O指令,而是通过操作系统来进行调用,操作系统在监控模式下,检查请求是否合法,如果合法,则处理I/O请求,然后返回给用户

所有的内存映射和I/O端口内存位置都受到内存保护系统的保护,以阻止用户访问,但是内核不能简单地拒绝所有用户访问。大多数图形游戏和视频编辑的软件需要直接访问内存映射的图形控制器内存来提高图像性能,内核在这种情况下,可能提供一种锁机制来使得图形内存的一部分能够每次分配给一个进程

这里写图片描述

最后

以上就是重要野狼为你收集整理的I/O内核的子系统的全部内容,希望文章能够帮你解决I/O内核的子系统所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部