Linux下的管道编程技术(3)

发表于:2013-03-06来源:开源黄页作者:天狼星点击数: 标签:linux
图2:示例代码1中半双工管道的示意图 这个例子中,通信是在具有共同祖先的进程间发生的,即父进程和子进程通信。这样做局限性太大,但我们只是用它

  图2:示例代码1中半双工管道的示意图

  这个例子中,通信是在具有共同祖先的进程间发生的,即父进程和子进程通信。这样做局限性太大,但我们只是用它来给读者一个感性的认识。接下来,我们将介绍更为高级的进程间的管道通信。

  2.进程间通信管道编程

  在利用管道技术进行编程时,处理要用到上面介绍的pipe函数外,还用到另外三个函数,如下所示。

   pipe函数:该函数用于创建一个新的匿名管道。

   dup函数:该函数用于拷贝文件描述符。

   mkfifo函数:该函数用于创建一个命名管道(fifo)。

  当然,在管道通信过程中还用到其它函数,到时我们会加以介绍。需要注意的是,说到底,管道无非就是一对文件描述符,因此任何能够操作文件操作符的函数都可以使用管道。这包括但不限于这些函数:select、read、write、 fcntl、freopen,等等。

  2.1函数pipe

  函数pipe用来建立一个新的管道,该管道用两个文件描述符进行描述。函数pipe的原型如下所示:

#include
int pipe( int fds[2] );

  当调用成功时,函数pipe返回值为0,否则返回值为-1。成功返回时,数组fds被填入两个有效的文件描述符。数组的第一个元素中的文件描述符供应用程序读取之用,数组的第二个元素中的文件描述符可以用来供应用程序写入。

  下 面我们考察在一个包含多个进程的应用程序中的管道示例。在该程序中(见示例代码2),第14行用于创建一个管道,然后进程在第16行分叉,变成一个父进程 和一个子进程。在子进程中,我们尝试从(在第18行建立的)管道的输入描述符读取,这时该进程将被挂起,直到管道中有可以读取的内容为止。

  读完后,我们用NULL作为读取的内容的结束符,这样的话,读的这些内容就能使用printf函数正确打印输出了。父进程先是利用存放在thePipe[1]中的“写文件标识符”向管道写入测试字符串,然后就使用wait函数来等待子进程退出。

  在 我们的这个程序中需要加以注意的是,我们的子进程是如何继承父进程利用pipe函数建立的文件描述符的,以及如何利用该文件描述符进行通信的。函数 fork一旦执行,子进程会继承父进程的功能和管道的文件描述符,但对于内核来说,父进程和子进程是平等的,它们是独立运行的。也就是说,两个进程分别具 有单独的内存空间,它们正是通过pipe函数来互通有无的。

示例代码2:演示两个进程间的管道模型的代码
1: #include
2: #include
3: #include
4: #include
5:
6: #define MAX_LINE 80
7:
8: int main()
9: ...{
10: int thePipe[2], ret;
11: char buf[MAX_LINE+1];
12: const char *testbuf=...{"a test string."};
13:

原文转自:http://yp.oss.org.cn/blog/show_resource.php?resource_id=598