13.4.15 管道的实现

来源:互联网 发布:分水岭算法原理 编辑:程序博客网 时间:2024/06/08 13:57


13.4.15  管道的实现

管道是UNIX提供的一种在两个进程间通信的机制。管道允许一个进程按照先进先出(First-In-First-Out,FIFO)的方式向另一个进程传送数据。它还可以用于不同进程间的同步。有两种类型的管道:命名管道和无名管道。就目前的讨论而言,可以忽略两者之间的差别。

从本质上讲,管道就是一个进程向其中写一些数据,而另一个进程从中按照写数据的顺序读这些数据的文件。因此,管道可以采用普通文件的形式实现,除了它需要两个文件偏移量或RBN之外:一个用于读操作,另一个用于写操作。管道和普通文件之间的差别如下:

(1) 管道在UFDT中有两个条目,在FT中有两个对应的条目,但在IT中只有一个条目。然而,两个文件偏移量是在索引节点中而不是FT条目中按照两个单独的字段维护的。这样做的原因在于:用于管道的系统调用同样被当作普通文件的系统调用。但该方案有一个潜在的问题:UNIX提供了可以改变FT中文件偏移量的用于文件随机搜索的系统调用。如果错误地将其用于管道,那么就会改变其中的一个偏移量,严格按照FIFO顺序写/读数据就会很危险,因而严重影响管道的实现。一种解决办法就是从用户/程序员角度,认为管道不同于文件。这样会导致采用比较复杂的实现方式。另一种办法就是在IT条目中维护偏移量,而不是在FT条目中。人们更喜欢采用后一种方法。

(2) 对管道文件而言,预留给它的索引节点只有10个直接块(0到9)。UNIX将管道大小限制在10个块或10 240个字节。因此,所有块号都可以放在索引节点自身中。它不使用任何间接块(索引)。这就是为什么对管道文件访问速度快的原因。

(3) 如果管道满了,就再次将指针设置到开始的地方,因而形成圆形缓冲区。然而,不能覆盖任何数据,除非该数据已经被读出。如果出现这种情况,该进程在唤醒想要从已经满了的管道中读取数据的进程后进入睡眠状态。读完一些数据后,管道就腾出一些接收新数据的空间。现在,向管道写数据的进程被唤醒,然后可以向管道写数据。

(4) 如果进程试图读取没有任何数据的空管道,该进程在唤醒想要写管道的进程后,它进入睡眠状态。在写完一些数据后,最初的进程被唤醒按照写数据的顺序读取数据。

记住:任何时候,不同进程间可以有多个管道。因此,通常系统将管道作为一个单独的文件系统实现,它有自己的索引节点和空闲数据块链表。

0 0
原创粉丝点击