进程间通信之管道

定义

管道是最古老的IPC方法,进程之间通过读写管道的fd进行通信。

性质

  1. 只有当所有的写入端fd都已经关闭,且管道中的数据都已经被读出,这时对读取端fd调用read函数才会返回0,也就是读到了EOF标识。
  2. 当所有的读取端fd都已经关闭,再向该管道写入数据时,写操作会失败,errno全局变量置为EPIPE,与此同时内核会向写入进程发送一个SIGPIPE的信号。
  3. 当所有的读取端fd和写入端fd都关闭以后,管道才能被销毁。

管道本质是一片内存区域,写入端通过fd[1]将数据写入这片内存,读取端通过fd[0]从这片内存读走数据。

使用场景

正常使用管道的场景,应该是关闭其它多余的管道文件描述符,只留两个进程和管道相关联,一个进程拥有管道的读取端,另一个进程拥有管道的写入端,实现一个进程写,另一个进程读的通信效果。

接口

创建管道:

  #include <unistd.h>
  
  int pipe(int pipefd[2]);

pipfd[2],管道的fd数组,pipefd[0]对应管道读取端,pipefd[1]对应管道的写入端

  #include <fcntl.h>
  #include <unistd.h>

  int pipe2(int pipefd[2], int flags);
  • 当flag为0时,pipe2()与pipe()功能完全一样
  • 当flag为O_CLOEXEC时,返回的pipefd[0]、pipefd[1]都带有FD_CLOEXEC属性
  • 当flag为O_NONBLOCK时,返回的pipefd[0]、pipefd[1]都带有O_NONBLOCK不阻塞属性

返回值:成功返回0,失败返回-1,可通过全局变量errno判断失败的原因

例子

创建一个管道,然后fork一个新的进程,让父进程和子进程通过管道进行通信

  #include<stdio.h>
  #include<stdlib.h>
  #include<unistd.h>
  #include<sys/types.h>
  #include<string.h>
  
  int main(int argv, char *argc[])
  {
      int pipe_fd[2];
      char buf[100];
      memset(buf,0,100);
      //创建管道
      if(pipe(pipe_fd)<0)
      {
          printf("creat pipe error.\n");
      }
      switch(fork())
      {
          case 0:
          //子进程,向管道写入数据
               close(pipe_fd[0]);
               write(pipe_fd[1],"hello,father.\n",15);
               printf("[child]send str:hello,father.\n");
               sleep(10);
               close(pipe_fd[1]);
          break;
          default:
          //父进程,从管道读取数据
               close(pipe_fd[1]);
               while(read(pipe_fd[0],buf,100))
               {
                   printf("[parent]recv str:%s\n",buf);
               }
               printf("child had closed pipefd.\n");
               close(pipe_fd[0]);
          break;
      }
      while(1);
  } 

运行结果:

  ./a.out 
  [child]send str:hello,father.
  [parent]recv str:hello,father.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值