进程之间通过管道通信1

  在Linux的shell命令中,可以通过管道操作符'|'来连接进程。在这里,我们通过使用pipe在程序中实现这种效果。

pipe函数原型如下:

      #include<stdio.h>

      int *pipe(int file_descriptor[2]);

  函数说明:

     file_descriptor为由两个整形的文件描述符组成的数组指针。写到file_descriptor[1]的所有数据都可以从file_descriptor[0]读回来。函数执行成功则返回0,否则返回-1。

示例1:子进程读取父进程信息

  创建pipe1.c文件,在这个程序,我们使用pipe来创建一个管道,由父进程给出autorName字符串并且写到file_descriptor[1]中,然后子进程从file_descriptor[0]中读出并显示。

 

  说明:我们开始调用pipe来创建一个管道,接着用fork映像出一个新的进程。forkResult的值为0时表示在子进程,为大于0的值在父进程。因此,子进程会执行case 0语句,而父进程会执行default语句。父进程将autorName字符串写入管道(file_descriptor[1]),而子进程从管道中读取出来(file_descriptor[0])。需要说明的是,两个进程是同时运行的。

  接下来,我们编译程序:

    $gcc -o pipe1 pipe1.c

  运行,效果如下:

  

  为什么上面的子进程打印出来的消息会在命令提示符后面呢?原因是父进程比子进程先结束!

示例2:不同的进程

  示例1我们是通过fork创建一个与父进程一模一样的进程,在接下来的示例中,我们使用的是两个不同的进程。在这个例子,我们使用了一个替换进程的函数execl()。

  编写pipe3.c文件:

  pipe4.c负责读取数据,如下:

  说明:pipe3.c的作用与pipe1.c的作用差不多,在父进程中,添加了由execl函数启动pipe4进程,execl的参数是:

  • 要启动的程序(包括路径)。
  • arg[0]: 程序名。
  • arg[1]:被启动的进程准备读取的文件描述符。
  • (char *)0:表示终止被调用程序的参数列表。

  pipe4被启动后,将通过read读取由execl传入的参数,编译并运行效果如下:

  解析:执行pipe3,首先父进程调用fork函数创建出一个与父进程一模一样的子进程。父进程调用write向管道(file_descriptor[1])写入autorName信息后,子进程通过使用sprintf函数向管道(file_descriptor[0])取数据(当管道数据为空时,子进程将会阻塞,直到有数据写入)。然后,一方面子进程调用execl函数,将子进程替换成pipe4进程,并把信息通过buffer传递给新的进程;另一方面,父进程打印出wirte data信息后结束进程,命令提示符出现。pipe4通过argv接收数据,并在命令提示符后面打印出来!

  注释:以上参考《linux程序设计》(第三版)。

posted @ 2014-08-30 18:55  Daying Yu  阅读(383)  评论(0编辑  收藏  举报