Linux入门篇——进程间通信之pipe无名管道

管道:从一个进程连接到另一个进程的数据量
无名管道:pipe
特点:
(1)用于具有血缘关系的进程间通信
(2)是一个只能单向通信的通信信道
(3)面向字节流
(4)自带同步机制,原子性写入
(5)管道也是文件,但它的生命周期是随进程的
相关函数:创建pipe:int pipe(int pipefd[2]);
参数:pipefd:是一个输出型参数,文件描述符数组,pipefd[0]表示读端,pipefd[1]表示写端
返回值:创建成功返回0,创建失败返回-1/错误代码
创建pipe

#include<stdio.h>
#include<unistd.h>

// pipe
int main(){
  int pipefd[2]={0};
  if(pipe(pipefd) != 0)
  {
    perror("pipe error");
    return 1;
  }

  printf("pipefd[0] = %d\n",pipefd[0]);
  printf("pipefd[1] = %d\n",pipefd[1]);
  return 0;
}

运行结果:
在这里插入图片描述
原因是pipefd[0]和pipedfd[1]都是文件描述符,0、1、2已被占用
pipe大小:64kb
通过计数器发现写入了65536个字符,65536个字符,即64kb便不再写入
在这里插入图片描述

在这里插入图片描述
父进程读,子进程写的代码实现:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
// pipe
int main(){

  int pipefd[2]={0};
  if(pipe(pipefd) != 0)
  {
    perror("pipe error");
    return 1;
  }
  printf("pipefd[0] = %d\n",pipefd[0]);
  printf("pipefd[1] = %d\n",pipefd[1]);

  // 实现父进程读取,子进程写入
  if(fork() == 0){
    // child
    
    close(pipefd[0]);
    const char *msg = "hello father\n";
    int count = 0;
    char c = 'a';
    while(1){
      write(pipefd[1],msg,strlen(msg));
      sleep(1);   
    }
    exit(0);
  }
  // father
  close(pipefd[1]);
  // 读
  while(1){
  
    char buffer[64] = {0};
    ssize_t s = read(pipefd[0],buffer,sizeof(buffer)-1);// 如果read的返回值=0,意味着子进程关闭

    if(s>0){
      buffer[s] = 0;
      printf("父进程收到了:%s\n",buffer);
      // 父进程没有sleep
    }else if(s == 0)
    {
      printf("child quit\n");
      break;
    }else{
      perror("read error");
      break;
    }
  }
  return 0;
}

管道读写的四种情况
读端读得慢或不读,写端等读端
读端关闭,写端收到SIGPIPE信号关闭
写端写得慢或不写,读端等写端
写端关闭,读端会读完pipe内部的数据后读到0,表明读到文件结尾

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值