Linux系统编程之父子进程通过管道进行通信

管道通信

1.pipe函数

创建管道

int pipe(int pipefd[2]);

返回值成功:0;失败:-1,设置 errno

函数调用成功返回 r/w 两个文件描述符。无需 open,但需手动 close。
规定:

fd[0] → r; fd[1] → w,

就像 0 对应标准输入,1 对应标准输出一样。向管道文件读写数据其实是在读写内核缓冲区。

2.父子进程通过管道通信步骤

建立一个父子进程间的管道通信主要通过以下几步

  1. 父进程调用 pipe 函数创建管道,得到两个文件描述符 fd[0]、fd[1]指向管道的读端和写端。
  2. 父进程调用 fork 创建子进程,那么子进程也有两个文件描述符指向同一管道
  3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。 由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。

3.创建一个父子进程通信管道

在这里插入图片描述

对父进程关闭读端close(fd[0]);子进程关闭写端close(fd[1]);

述

实现了父进程往管道里写入,子进程从管道读出

4.利用进程间通信实现ls | wc -l 指令

实现ls | wc -l.

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>

int main (int argc ,char * argv[])
{
    int fd1,fd2,ret;
    int fd[2];
    ret = pipe(fd); //创建管道
    if (ret == -1)
    {
        perror("pipe error");
    }
    pid_t pid = fork();
    if (pid == -1)
    {
        perror("fork error");
        exit(1);
    
    }else if (pid > 0) //父进程
    {
       
        close(fd[0]);
        dup2(fd[1],STDOUT_FILENO);
        execlp("ls","ls",NULL);
        perror("execlp error");
       
    }else if (pid == 0)  //子进程
    {  
        close(fd[1]);
        dup2(fd[0],STDIN_FILENO);
        execlp("wc","wc","-l",NULL);    
    }
}

5.兄弟进程间通过管道通信

兄弟进程间通信

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/wait.h>
int main (int argc ,char * argv[])
{
    int ret,i;
    int fd[2];
    ret = pipe(fd);
    if (ret == -1)
    {
        perror("pipe error");
    }
    for (i = 0; i < 2; i++)
    {
        pid_t pid = fork();
        if (pid == -1)
      {
        perror("fork error");
        exit(1);

      } 
      if (pid == 0)
      {
          break;
      }
      
    }
    if (i == 0) //哥哥进程
    {
        //fd1 = open("fc.out",O_RDWR|O_CREAT|O_TRUNC,0777);
        close(fd[0]);
        dup2(fd[1],STDOUT_FILENO);
        execlp("ls","ls",NULL);
        perror("execlp error");
        
        
    }else if (i == 1)  //弟弟进程
    {
        
        //fd2 = open("fc.out",O_RDWR,0777);
        //dup2(STDOUT_FILENO,fd2);
        close(fd[1]);
        dup2(fd[0],STDIN_FILENO);
        execlp("wc","wc","-l",NULL);
        //close(fd2); 
    }else if (i == 2)
    {
        close(fd[0]);
        close(fd[1]);
        wait(NULL);
        wait(NULL);
    }       
}
  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值