进程间通信——管道

进程间通信——管道
管道简介
常说的管道都是匿名半双工管道,匿名半双工管道在系统中是没有实名的,并不可以在文件系统中以任何方式看到该管道。它只是进程的一种资源,会随着进程的结束而被系统清除。管道通信是在UNIX系统中应用比较频繁的一种方式,例如使用grep查找:ls |grep ipc
顾名思义,匿名半双工管道没有名字,这个特性导致了它在应用方面的局限性:
       1.只能在有具有公共祖先的进程间通信,即或是父子关系进程间、或是在兄弟关系进程间通信。
       2.数据只能在一个方向上移动
管道创建
尽管这样,半双工管道还是Linux系统上最常见的通信方式。Linux系统用pipe函数创建一个半双工管道,期函数原型为:
        include<unistd.h>
        int pipe(int fd[2]);
     参数fd是一个长度为2的文件描述符,fd[1]为输入文件描述符,fd[1]为输出文件描述符;函数返回类型为int,0表示成功,-1表示失败。当成功返回时,则自动维护一个从fd[1]到fd[0]的同行管道。
管道操作
对管道进行读写,可以通过write和read进行:
            write(fd[1], "create the pipe successfully !\n", 31 ); /*向管道写入端写入数据*/
                     char str[256];
                     read(fd[0], str, sizeof(str) ); /*从管道读出端读出数据*/
       读写时,需要注意的问题:
                     1.当输出端关闭时,对输入端的写操作会产生信号SIGPIPE,说明管道读端已经关闭,并且write操作返回为–1,errno的值为EPIPE,对于SIGPIPE信号可以进行捕捉处理。
            2.read返回0说明管道中没数据,但不能说明输入端是否关闭
操作流程
    1.创建管道
    2.利用fork创建子进程
    3.控制管道流向
    4.从fd[1]向管道写信息
    5.通过fd[0]从管道渡信息
创建管道的标准库函数
     #include <stdio.h>
         FILE *popen( const char * command, const char *mode ); 
         int pclose ( FILE *stream );  
示例
引用《Linux C程序设计大全》 中的例子

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <fcntl.h>
  4. #include <sys/types.h>
  5. #define BUFES PIPE_BUF /* PIPE_BUF管道默认一次性读写的数据长度*/
  6. int main ( void ) {
  7.          int fd[2];
  8.          char buf[BUFSZ];
  9.          pid_t pid;
  10.          int len;
  11.          if ( (pipe(fd)) < 0 ){ /*创建管道*/
  12.                   perror ( "failed to pipe" );
  13.                   exit( 1 );
  14.          }
  15.          if ( (pid = fork()) < 0 ){ /* 创建一个子进程 */
  16.                   perror ( "failed to fork " );
  17.                   exit( 1 );
  18.          }
  19.          else if ( pid > 0 ){
  20.                 close ( fd[0] ); /*父进程中关闭管道的读出端*/
  21.                  write (fd[1], "hello my son!\n", 14 ); /*父进程向管道写入数据*/
  22.                  exit ( 0);
  23.          }
  24.          else {
  25.                  close ( fd[1] ); /*子进程关闭管道的写入端*/
  26.                 len = read (fd[0], buf, BUFS ); /*子进程从管道中读出数据*/
  27.         if ( len < 0 ){
  28.                  perror ( "process failed when read a pipe " );
  29.                  exit( 1 );
  30.         }
  31.          else
  32.                  write(STDOUT_FILENO, buf, len); /*输出到标准输出*/
  33.                  exit(0);
  34.          }
  35. }
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(375) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~
评论热议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值