Linux IPC:管道符的实现

本文介绍了管道符的概念及其作用,如`ps-ef|grep./test`示例。接着详细阐述了如何模拟实现管道符,涉及匿名管道的创建、子进程的程序替换以及输入/输出重定向。在模拟过程中,创建两个子进程分别运行`ps`和`grep`,通过匿名管道进行数据传输,实现了类似管道符的功能。
摘要由CSDN通过智能技术生成

  本文主要了解如何模拟实现管道符,要使用的知识点:管道符、匿名管道、输出/输入重定向、程序替换。

一、了解管道符

管道符:|

  管道符的作用可以结合下面的例子来了解一下:

  • ps -ef | grep ./test

  ps -ef:打印系统中的进程信息到标准输出。

  grep ./test:搜索文件中包含./test的行并打印

  管道符的作用就是将 ps -ef 中原本要打印到标准输出的信息转交给 grep ./test,然后grep程序就把这些信息中包含有./test的行打印出来。

二、实现管道符

来看看管道符的模拟实现流程:

  因为我们使用的是匿名管道,因此首先要在父进程中创建匿名管道,然后才可以创建子进程,这样子进程就可以与父进程访问同一个匿名管道。

  由于程序中涉及到两个程序:ps和grep,因此我们要创建两个子进程p1和p2。两个子进程的作用就是进行程序替换,一个运行ps程序,一个运行grep程序。

  ps程序会把数据输出到标准输出,grep原本会从标准输出中接收数据并筛选,管道符将它们连接起来。

  我们将子进程p1和p2进行程序替换后,两个进程之间无法直接传递数据,因此需要使用匿名管道来进行数据的传输。ps子进程将数据发送到匿名管道,grep子进程从匿名管道读取数据并筛选。因此两个子进程还需要进行输入输出重定向才可以实现上面的功能。

  子进程p1:首先进行输出重定向,将原本要输出到标准输出的数据发送到匿名管道,然后进行程序替换运行ps程序。

  子进程p2:首先进行输入重定向,将原本要从标准输入读取的数据改成从匿名管道读取,然后进行程序替换运行grep程序。

  注意:ps程序在将数据发送到匿名管道后就会退出,但grep程序会一直等待,因为如果管道的写端没有全部关闭,管道的读端就不会退出。因此如果要想让grep程序打印完后退出,就要关闭所有写端(包括父进程的)。

为什么程序替换后,输入输出重定向依然有效?

 因为程序替换更新的是虚拟地址空间,页表信息,但IO信息不会初始化。

 如下是模拟实现管道符的代码:

#include<stdio.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

//使用匿名管道实现管道符
// ps -ef | grep realiz_pipe
int main(){
  int pipefd[2];//输出参数
  int ret = pipe(pipefd);//创建匿名管道
  if(ret == -1){
    printf("匿名管道创建失败\n");
    return -1;
  }

  pid_t p1 = fork();//创建子进程p1运行ps
  if(p1 == 0){
    dup2(pipefd[1],1);//输出重定向
    execlp("ps","ps","-ef",NULL);//进行程序替换
    exit(-1);//替换失败才会运行到这里
  }
  
  pid_t p2 = fork();//创建子进程p2运行grep
  if(p2 == 0){
    close(pipefd[1]);//关闭写端,否则grep会一直等待
    dup2(pipefd[0],0);//输入重定向
    execlp("grep","grep","realiz_pipe",NULL);//进行程序替换
    exit(-1);
  }
  close(pipefd[0]);
  close(pipefd[1]);//所有写端都被关闭后,读端才会关闭
  wait(NULL);//处理退出的子进程
  wait(NULL);
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值