简介
在本章当中www.cechina.cn,我们将学习GNU/Linux管道。管道模型虽然很老但是就算是现在它仍然是一个十分有用的进程间通信机制。我们将会学习什么是半双向管道以及有名管道。它们都提供了一个FIFO(先进先出)排队模型来允许进程间通信。
管道模型
一个形象化管道的描述为--一个在两个实体之间的单向连接器。例如www.cechina.cn,让我们来看一看下面的这个GNU/Linux命令:
ls -1 | wc -l
这个命令创建了两个进程www.cechina.cn,一个和ls -l关联而另一个则和wc -l关联。接着它通过设置第二个进程的标准输入到第一个进程的标准输出连接了这两个进程(如图11.1)。产生的结果是--计算了当前子目录的文件数目。
我们的命令设置了一个在两个GNU/Linux命令之间的管道。命令ls被执行之后它产生的输出被用作第二个命令wc(word count)的输入。这是一个单向管道--通信发生在一个方向上。两个命令之间的连接由GNU/Linux来完成。我们也可以在应用程序当中做到这一点(等一下我们将会证明这一点)。
匿名管道和有名管道
一个匿名管道或者说单向管道,
管道的另一种类型是有名管道。一个有名管道其功能和匿名管道差不多,差别就在于它是可以在文件系统中存在的并且所有进程都可以找到它。这意味着没有血缘关系的进程之间可以使用它来进行通信。
在接下来的部分当中我们将会同时学习有名管道和匿名管道。我们将对管道进行一个快速的游览,然后我们就详细地学习管道API以及支持管道编程的GNU/Linux系统级的命令。
旋风式的游览
让我们以一个简单的管道编程的模型的例子来开始我们的旋风式游览。在这个简单的例子当中,我们在一个进程当中创建了一个管道,然后对它写入一个消息,接下来的就是从这个管道当中读取前面写入的消息,然后将它显示出来。
清单11.1: 一个简单的管道例子
1:#include <unistd.h>
2:#include <stdio.h>
3:#include <string.h>
4:
5:#define MAX_LINE 80
6:#define PIPE_STDIN 0
7: #define PIPE_STDOUT 1
8:
9: int main()
10: {
11: const char *string={"A sample message."};
12: int ret, myPipe[2];
13: char buffer[MAX_LINE+1];
14:
15: /* Create the pipe */
16: ret = pipe( myPipe );
17:
18: if (ret == 0) {
19:
20: /* Write t