10.5 Linux中的I/O系统

Linux和其他的UNIX系统一样,I/O系统都相当的简单明了。基本上,所有的I/O设备都被当作文件来处理,并且通过与访问所有文件同样的read和write系统调用来访问。在某些情况下,必须通过一个特殊的系统调用来设置设备的参数。我们会在下面的章节中学习这些细节。

10.5.1 基本概念

像所有的计算机一样,运行Linux的计算机具有磁盘、打印机、网络等I/O设备。需要一些策略才能使程序能够访问这些设备。有很多不同的方法都可以达到目的,Linux把设备当作一种特殊文件整合到文件系统中。每个I/O设备都被分配了一条路径,通常在/dev目录下。例如:一个磁盘的路径可能是“/dev/hd1”,一个打印机的路径可能是“/dev/lp”,网络的路径可能是“/dev/net”。

可以用与访问其他普通文件相同的方式来访问这些特殊文件。不需要特殊的命令或者系统调用。常用的open、read、write等系统调用就够用了。例如:下面的命令

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元


cp file/dev/lp


把文件“file”复制到打印机“/dev/lp”,然后开始打印(假设用户具有访问“/dev/lp”的权限)。程序能够像操作普通文件那样打开、读、写特殊文件。实际上,上面的“cp”命令甚至不知道是要打印“file”文件。通过这种方法,不需要任何特殊的机制就能进行I/O。

特殊文件(设备)分为两类,块特殊文件和字符特殊文件。一个块特殊文件由一组具有编号的块组成。块特殊文件的主要特性是:每一个块都能够被独立地寻址和访问。也就是说,一个程序能够打开一个块特殊文件,并且不用读第0块到第123块就能够读第124块。磁盘就是块特殊文件的典型应用。

字符特殊文件通常用于表示输入和输出字符流的设备。键盘、打印机、网络、鼠标、绘图机以及大部分接受用户数据或向用户输出数据的设备都使用字符特殊文件来表示。访问一个鼠标的124块是不可能的(甚至是无意义的)。

每个特殊文件都和一个处理其对应设备的设备驱动相关联。每个驱动程序都通过一个主设备号来标识。如果一个驱动程序支持多个设备,如,相同类型的两个磁盘,每个磁盘使用一个次设备号来标识。主设备号和次设备号结合在一起能够惟一地确定每个I/O设备。在很少的情况下,一个单独的驱动程序处理两种关系密切的设备。比如:与“/dev/tty”联合的驱动程序同时控制着键盘和显示器,这两种设备通常被认为是一种设备,即终端。

大部分的字符特殊文件都不能够被随机访问,因此它们通常需要用不同于块特殊文件的方式来控制。比如,由键盘上键入输入字符并显示在显示器上。当一个用户键入了一个错误的字符,并且想取消键入的最后一个字符时,他敲击其他的键。有人喜欢使用“backspace”回退键,也有人喜欢“del”删除键。类似地,为了取消刚键入的一行字符,也有很多方法。传统的方法是输入“@”,但是随着e-mail的传播(在电子邮件地址中使用@),一些系统使用“CTRL+U”或者其他字符来达到目的。同样的,为了中断正在运行的程序,需要使用一些特殊的键。不同的人有不同的偏爱。“CTRL+C”是常用的方法,但不是惟一的。

Linux允许用户自定义这些特殊的功能,而不是强迫每个人使用系统选择的那种。Linux提供了一个专门的系统调用来设置这些选项。这个系统调用也处理tab扩展,字符输出有效、失效,回车和换行之间的转换等类似的功能。这个系统调用不能用于普通文件和块特殊文件。