主要内容是主机交互方式、阻塞非阻塞方式、IO内核子系统功能
文章目录
概述
名词解释:
- **端口:**设备与计算机通信的连接点。
- **总线:**一组线和一组严格定义了线上传输信息的协议。
- **链环:**设备A通过电缆连接到设备B上,设备B又通过电缆连接到设备C上,设备C通过端口连接到计算机上,这种方式成为链环。
- **控制器:**是用于操作端口、总线或者设备的一组电子器件。
控制器有一个或多个用于数据和控制信号的寄存器。处理器通过读写这些寄存器的位模式来与控制器通信。
处理器执行IO请求是通过标准数据传输指令来完成对设备控制器的读写。
https://blog.csdn.net/leftfist/article/details/50167147
与主机的交互
主机与控制器之间交互的完成协议用很多。
轮询
轮询也就是基本的握手原则。
有两个位来协调控制器和主机之间生产者和消费者的关系。其中控制器通过状态寄存器的**忙位(busy bit)**来显示其状态,控制器工作忙时置忙位,可以接收命令时就清忙位。
置位(set a bit)是将1写到位中,清位(clear a bit)是将0写到位中。
主机通过命令寄存器中命令就绪位表示其意愿。
当主机有命令需要控制器执行时,就置命令就绪位。
主机与控制器的握手协议:
- 主机不断读取忙位,直到该位被清除。
- 主机设置命令寄存器中的写位并向数据输出寄存器中写入下一个字节。
- 主机设置命令就绪位
- 控制器注意到命令就绪位已经被设置后,置忙位。
- 控制器读取命令存储器,看到写命令,并从数据输出寄存器中读取一个字节,向设备执行IO操作。
- 控制器清除命令就绪位,清除状态寄存器的故障位表示设备IO成功,清楚忙位表示完成。
在第一步时,主机处于忙等待(busy-waiting)或轮询(polling)中,即在循环中不断读取状态寄存器直到忙位被清除。因此该方法适用于控制器和设备都比较快的情况
中断
让设备准备好时再通知处理器,这样的效率会更高,这种外设通知CPU的硬件机制称为中断(interrupt)。
设备控制器通过中断请求线发送信号引起(raise)中断,CPU 捕获中断并分发到中断处理程序中,中断处理程序通过处理设备请求来清除中断。
进入中断前,CPU保存当前状态;完成中断后,CPU执行中断返回指令以便使CPU返回中断以前的执行状态。
绝大多数CPU有两个中断请求线:
- 非屏蔽中断,用于处理如不可恢复内存错误等事件。
- 可屏蔽中断,这可以由CPU在执行关键的不可中断的指令序列前加以屏蔽
中断机制接受一个地址,以用来从一小集合内选择特定的中断处理程序。对绝大多数体系结构,这个地址是一个称为中断向量(interrupt vector)的表中偏移量。该向量包含了特殊中断处理程序的内存地址。
向量中断机制的目的是用来减少单个中断处理的需要。
中断机制也实现了中断优先级(interrupt priority),该中断机制能使CPU延迟处理低优先级中断而不屏蔽所有中断,也可以让高优先级中断抢占低优先级中断处理。
直接内存访问
对于需要做大量传输的设备,例如磁盘,耗费CPU来观察寄存器太浪费,通常将任务下方给专用处理器,称之为直接内存访问(DMA)控制器。
CPU向内存写入数据,然后就继续忙别的,DMA控制器接手进行数据传输,完成以后中断通知CPU。
IO应用接口
IO应用接口使得IO设备可以按统一的标准方式来对待。
具体来说,从不同的IO设备中抽象出通用类型,每个通用类型都可以通过一组标准函数(即接口)来访问。具体的差别被**内核模块(设备驱动程序)**所封装。
设备驱动程序层的作用就是为内核IO子系统隐藏设备控制器之间的差异。
不利的因素是每种操作系统都有自己的接口标准,一个设备可能有多种驱动程序。
设备在许多方面都有很大差异:
- 字符流或块:字符流设备以一个字节为单位进行传输,而块设备以块为单位
- 顺序访问或者随机访问
- 同步或者异步:指响应时间一定或者不可预测的随机响应时间
- 共享或专用:共享设备可以被多个进程、线程并发使用,专用设备不行。
- 操作速度
- 读写、只读、只写:有的设备支持读写,有的设备只支持单向数据操作
对应用程序而言,设备的许多差别都被操作系统所隐藏,设备可以分为几种类型:块与字符设备,网络设备,时钟与定时器等。
块与字符设备
块设备接口规定了访问磁盘驱动器和其他基于块设备所需要的各个方面。通常设备有read()
、write()
、seek()
命令
seek()命令是随机访问设备持有的,用于描述下次传输哪个块。
操作系统本身和特殊应用程序(如数据库管理系统)可能更加倾向于将块设备当做一个简单的线性块数组来访问。这种访问方式有时称为原始IO。
即不经过文件系统,直接访问硬盘。
内存映射文件
内存映射文件访问是建立在块设备驱动程序之上的。内存映射接口并不提供read和write操作,而是通过内存中的字节数组来访问磁盘存储。
因为传输采用了与按需分页虚拟内存访问相同的机制,所以内存映射IO比较高效。
键盘
键盘是一种可以通过字符流接口访问的设备。其常用的命令有get()
、put()
。
在此接口之上,可以构造库以提供具有缓冲和编辑功能的按行访问。
网络设备
由于网络IO的性能和访问特点与磁盘IO相比有很大差别,许多操作系统所提供的接口是网络Socket接口。
Socket接口的系统调用可以让应用程序创建一个Socket,连接本地Socket和远程Socket。
为支持服务器的实现,Socket接口还提供了
select()
函数,以管理一组Socket。这些函数封装了基本的网络功能,大大地加快了使用网络硬件和网络协议的分布应用程序的创建。
时钟和定时器
许多计算机都有硬件时钟和定时器以提供如下三个基本函数:
- 获取当前时间
- 获取已经逝去的时间
- 设置定时器,以在T时触发操作X
可编程间隔定时器(programmable interval timer)是测量逝去时间和触发操作的硬件。它可被设置等待一定的时间,并触发中断,或者设置重复次数,以产生周期性中断。
阻塞和非阻塞IO
当应用程序发出阻塞系统调用时,应用程序的执行被挂起,应用程序将会从操作系统的运行队列移到等待队列上去。在系统调用完成后,应用程序就移回到运行队列,并在合适的时候继续执行并能收到系统调用返回的值。
由IO设备执行的物理动作常常是异步的,因为其执行时间可变或不可预计。但绝大多数操作系统为应用程序接口使用阻塞系统调用,这是因为阻塞应用代码比非阻塞应用代码更容易理解。
但阻塞系统调用显然不能满足所有的需要,有的用户级进程需要使用非阻塞IO,如接受键盘和鼠标输入的同时处理在屏幕上显示数据。
非阻塞IO的实现方式之一是通过编写多线程应用程序。有的线程执行阻塞系统调用,而其他线程继续执行。
一个非阻塞调用在程序执行过长时间时并不中止应用程序,它会很快返回,其返回值表示已经传输了多少字节。
除了非阻塞IO,还有异步系统调用。
异步系统调用不必等待IO完成即可立即返回。应用程序继续执行其代码,并在将来IO完成时候可以通知应用程序。
通知方式可以是设置应用程序地址空间内的某个变量,或通过触发信号或软件中断。
非阻塞与异步系统调用的差别是非阻塞read()调用会马上返回任何可用的数据,其所读的数据可以等于或少于所要求的,或为0。异步read()调用所要求的传输应该完整的执行,但其具体执行可以是将来某个特定时间。
IO内核子系统
内核中许多与IO有关的服务是由内核IO子系统提供的,并建立在硬件和设备驱动程序结构之上。IO子系统还负责保护自己免受错误进程和恶意用户的危害。
IO调度
IO调度就是确定一个合适的顺序来执行IO请求。通过调度来改善性能。
调度可由开发人员实现,也可以由操作系统分配。
IO子系统改善计算机效率的方法之一就是IO操作调度,另外一种方法是使用主存或磁盘上的存储空间技术,如缓冲、高速缓存、假脱机等。
缓冲
缓冲区是用来保存两个设备之间或设备和应用程序之间所传输数据的内存区域。
这样做有三个理由:
- 处理数据流的生产者与消费者之间的速度有差异
- 协调传输数据大小不一致的设备
- 支持应用程序IO的复制语义。所谓复制语义,就是处理前先对数据进行复制,保证处理过程中不受数据源发生变化所影响。
高速缓存
高速缓存是可以保留数据副本的高速存储器。
高速缓存副本的访问要比原始数据访问更高效。
高速缓存与缓冲是两个不同的功能。但有时一块内存区域也可以同时用于这两个目的。
假脱机与设备预留
**假脱机(Spooling)**是用来保存设备输出的缓冲区,这些设备(如打印机)不能接受交叉的数据流。
当应用程序完成打印时,假脱机系统将对相应的待送打印机的假脱机文件进行排队。
错误处理
采用内存保护的操作系统可以预防许多硬件和应用程序的错误,这样就不会因为小的机械失灵导致系统崩溃。
IO系统调用通常返回一个位来表示调用状态信息,以表示成功或失败。
当然,有的硬件也能提供很详细的出错信息。
IO保护
- 为了防止用户执行非法IO,定义所有IO指令为特权指令
- 用户不能直接发出IO指令,只能通过操作系统来进行。
另外,所有内存映射和IO端口内存位置都受到内存保护系统的保护,以阻止用户访问。
但是内核不能简单地拒绝所有用户访问, 因为有些软件需要直接访问内存映射来提高性能,需要内核采取锁机制来应对。
内核数据结构
内核需要保存IO组件使用的状态信息,可以通过若干内核数据结构如文件打开表等来完成。
UNIX提供对若干实体,如用户文件、原设备和进程地址空间的文件系统访问。
有的操作系统通过使用面向对象方法(如消息传递)来实现IO
IO子系统小结
总而言之,IO子系统负责:
- 文件和设备的命名空间的管理
- 文件和设备的访问控制
- 操作控制
- 文件系统空间分配
- 设备分配
- 缓冲、高速缓存和假脱机
- IO调度
- 设备状态监控、错误处理以及失败恢复
- 设备驱动程序的配置和初始化
把IO操作转换成硬件操作*
流*
性能
网络传输是导致高上下文切换率的一个因素。
- 本地计算机上,每输入一个字符,都会产生一个中断。
- 该字符通过中断处理程序传给设备驱动程序,再传给内核,最后到用户进程。
- 用户进程执行一个网络IO系统调用来将该字符送到远程计算机。
- 该字符流入本地内核,通过构造网络包的网络层,再到网络设备驱动程序。
- 网络设备驱动程序将该包送交网络控制器以发送该字符并产生中断
- 该中断回传到内核以完成网络IO系统调用。
- 远程系统的网络硬件收到包,并产生中断。
- 该字符被网络协议解包后再送给网络服务程序。
- 网络服务程序确定与哪个远程登录会话有关,进而将该包交给合适会话的子服务程序。