Linux IPC: Implementation of the pipe character

  This article mainly understands how to simulate and implement pipe symbols, and the knowledge points to be used: pipe symbols, anonymous pipes, output/input redirection, and program replacement.

First, understand the pipe symbol

Pipe character: |

  The role of the pipe character can be combined with the following example to understand:

  • ps -ef | grep ./test

  ps -ef: Print process information in the system to standard output.

  grep ./test: Search for lines containing ./test in the file and print

  The role of the pipe character is to transfer the information originally to be printed to the standard output in ps -ef to grep ./test, and then the grep program prints out the lines containing ./test in the information.

Second, implement the pipeline symbol

Let's take a look at the simulation implementation process of the pipe symbol:

  Because we are using an anonymous pipe, we must first create an anonymous pipe in the parent process before creating a child process, so that the child process can access the same anonymous pipe as the parent process.

  Since the program involves two programs: ps and grep, we need to create two subprocesses p1 and p2. The function of the two child processes is to perform program replacement, one runs the ps program, and the other runs the grep program.

  The ps program will output the data to standard output, and grep would have received and filtered data from standard output, and the pipe character will connect them.

  After we replace the subprocesses p1 and p2 with programs, data cannot be directly transmitted between the two processes, so anonymous pipes need to be used for data transmission. The ps subprocess sends data to the anonymous pipe, and the grep subprocess reads and filters data from the anonymous pipe. Therefore, the two child processes also need to perform input and output redirection to achieve the above functions.

  Subprocess p1: First, output redirection, send the data originally output to the standard output to the anonymous pipe, and then perform program replacement and run the ps program.

  Subprocess p2: First, redirect the input, change the data originally to be read from the standard input to read from the anonymous pipe, and then perform program replacement and run the grep program.

  Note: The ps program will exit after sending data to the anonymous pipe, but the grep program will wait forever, because the read end of the pipe will not exit if the write end of the pipe is not fully closed. Therefore, if you want the grep program to exit after printing, you must close all write terminals (including the parent process).

Why does input and output redirection still work after program replacement?

 Because the program replacement updates the virtual address space and page table information, but the IO information will not be initialized.

 The following is the code for simulating the pipe symbol:

#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);
}

Guess you like

Origin blog.csdn.net/weixin_57761086/article/details/128525224