2.6 I/O System

2009-05-13 08:27:30来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折


UNIX I/O系统的基本模型是一个可以被随机或顺序访问的字节序列。在典型UNIX用户进程中没有访问方法和控制块。
不同的应用程序期望不同的结构标准,但是内核不能把特定结构强加到I/O上。例如,文本文件的标准是被换行符分割的ASCII字符行,但是内核对这个标准完全不知。为了适应大部分应用程序的需要,I/O模型被更简单化成一个字节数据流或者一个I/O流。这是简单通用的数据模型,成为UNIX的特性,是UNIX工作的基础。一个I/O流可以从一个程序流向几乎其他任何程序。
描述符和I/O
UNIX进程使用描述符来引用I/O流。描述符是一个从open或socket系统调用获得的small unsigned int类型的变量。调用open需要文件名和许可模式两个参数,许可模式用来指定被打开的文件是否可读、可写或者可读写。这个系统调用也可以用来创建一个新的空文件。read和write系统调用可以用描述符来传递数据。close系统调用可以回收任何描述符。
描述符描述被内核支持的对象,被特定对象类型的系统调用创建。在FreeBSD中,描述符可以描述四种类型的对象:file(文件)、pipe(管道)、fifo和socket。

  • 一个file是一个至少有一个名字的线性字节数组。一个文件一直存在,直到它的所有名字被明确的删除而且没有任何进程操作它的描述符。一个进程用文件名做参数调用系统调用open来打开一个文件,从而获得文件描述符。I/O设备也是作为文件来访问的。
  • 一个管道是一个线性字节数组,它也是一个文件,但是它被单独作为I/O流被来使用,并且是单向的。它没有名字,因此不能用open打开。而是用系统调用pipe创建。这个系统调用返回两个描述符,其中一个接受输入,并可靠的发送给另外一个描述符。这些数据是顺序的,没有副本。
  • 一个fifo通常是指命名管道。一个fifo除了在文件系统中可见外,它与一个pipe有相同的属性。因此它可以用open来打开。两个想通讯的进程各自打开同一个fifo,其中一个用来读,而另外一个用来写。
  • socket是用于进程间通讯的一个临时对象。它仅仅在进程操作它的描述符时存在。使用系统调用socket来创建一个socket,这个系统调用返回一个描述符。有不同种类的socket支持各种通讯语义,比如数据的可靠传输、保存消息顺序、保存消息边界。

在4.2BSD以前的系统里,pipe是用文件系统实现的。当4.2BSD中引入了socket,pipe就作为socket来实现了。由于效率的原因,FreeBSD不再使用socket来实现pipe和fifo。而是单独实现以优化本地通讯。
内核为每个进程维护一张描述符表。内核用这个表来吧一个描述符从外部表示法翻译成内部表示法。描述符仅仅是这张表的索引号。进程的描述符表是从父进程继承来的,因此描述符描述的对象也是继承的。进程获得描述符主要有两个途径:
  • 通过打开或创建一个对象。
  • 从父进程继承。
    另外,socket IPC运行在运行在同一台机器上的进程之间通过消息传递描述符。
    每个有效的描述符都有一个和它相联系的文件偏移,这个偏移从对象的开始部分算起,以字节为单位。读写操作都从这个偏移开始,每次数据传输后都会更新文件偏移。对于允许随机访问的对象,它的文件偏移也可以使用lseek系统调用来设置。普通的文件允许随机访问,有些设备文件也允许随机访问。但是pipe、fifo和socket不允许随机访问。
    当一个进程终止时,进程会回收该进程使用的所有描述符。如果这个进程持有对象的最后一个引用,此时对象管理器会被通知,以便采取必要的清除操作。比如最终的文件删除或者socket的空间回收。
    描述符管理
    大多数进程开始运行时有三个描述符已经被打开。这三个描述符是0、1和2,分别是标准输入、标准输出和标准错误。通常登录进程把这三个描述符与用户的终端关联在一起(参加14.5节),通过用户运行的进程调用fork和exec来继承。因此,一个程序能够通过读标准输入来读取用户的输入,通过写标准输出来吧信息显示在用户的屏幕上。标准错误描述符也是为写入而打开的,用于错误的输出,而标准输出用于一般的输出。

    标签:

    版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

  • 上一篇:UNIX系统操作命令

    下一篇:PF Manual