预计阅读本页时间:-
5.2 I/O软件原理
在讨论了I/O硬件之后,下面我们来看一看I/O软件。首先我们将看一看I/O软件的目标,然后从操作系统的观点来看一看I/O实现的不同方法。
5.2.1 I/O软件的目标
在设计I/O软件时一个关键的概念是设备独立性(device independence)。它的意思是应该能够编写出这样的程序:它可以访问任意I/O设备而无需事先指定设备。例如,读取一个文件作为输入的程序应该能够在硬盘、CD-ROM、DVD或者USB盘上读取文件,无需为每一种不同的设备修改程序。类似地,用户应该能够键入这样一条命令
sort<input>output
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
并且无论输入来自任意类型的存储盘或者键盘,输出送往任意类型的存储盘或者屏幕,上述命令都可以工作。尽管这些设备实际上差别很大,需要非常不同的命令序列来读或写,但这一事实所带来的问题将由操作系统负责处理。
与设备独立性密切相关的是统一命名(uniform naming)这一目标。一个文件或一个设备的名字应该是一个简单的字符串或一个整数,它不应依赖于设备。在UNIX系统中,所有存储盘都能以任意方式集成到文件系统层次结构中,因此,用户不必知道哪个名字对应于哪台设备。例如,一个USB盘可以安装(mount)到目录/usr/ast/backup下,这样复制一个文件到/usr/ast/backup/monday就是将文件复制到USB盘上。用这种方法,所有文件和设备都采用相同的方式——路径名进行寻址。
I/O软件的另一个重要问题是错误处理(error handling)。一般来说,错误应该尽可能地在接近硬件的层面得到处理。当控制器发现了一个读错误时,如果它能够处理那么就应该自己设法纠正这一错误。如果控制器处理不了,那么设备驱动程序应当予以处理,可能只需重读一次这块数据就正确了。很多错误是偶然性的,例如,磁盘读写头上的灰尘导致读写错误时,重复该操作,错误经常就会消失。只有在低层软件处理不了的情况下,才将错误上交高层处理。在许多情况下,错误恢复可以在低层透明地得到解决,而高层软件甚至不知道存在这一错误。
另一个关键问题是同步(synchronous)(即阻塞)和异步(asynchronous)(即中断驱动)传输。大多数物理I/O是异步的——CPU启动传输后便转去做其他工作,直到中断发生。如果I/O操作是阻塞的,那么用户程序就更加容易编写——在read系统调用之后,程序将自动被挂起,直到缓冲区中的数据准备好。正是操作系统使实际上是中断驱动的操作变为在用户程序看来是阻塞式的操作。
I/O软件的另一个问题是缓冲(buffering)。数据离开一个设备之后通常并不能直接存放到其最终的目的地。例如,从网络上进来一个数据包时,直到将该数据包存放在某个地方并对其进行检查,操作系统才知道要将其置于何处。此外,某些设备具有严格的实时约束(例如,数字音频设备),所以数据必须预先放置到输出缓冲区之中,从而消除缓冲区填满速率和缓冲区清空速率之间的相互影响,以避免缓冲区欠载。缓冲涉及大量的复制工作,并且经常对I/O性能有重大影响。
此处我们将提到的最后一个概念是共享设备和独占设备的问题。有些I/O设备(如磁盘)能够同时让多个用户使用。多个用户同时在同一磁盘上打开文件不会引起什么问题。其他设备(如磁带机)则必须由单个用户独占使用,直到该用户使用完,另一个用户才能拥有该磁带机。让两个或更多的用户随机地将交叉混杂的数据块写入相同的磁带是注定不能工作的。独占(非共享)设备的引入也带来了各种各样的问题,如死锁。同样,操作系统必须能够处理共享设备和独占设备以避免问题发生。