2.13 Anonymous pipe communication case

In the previous program example 3, there is actually an error. For example, in the figure below, the parent process not only receives the data sent by the child process, but sometimes also receives the data sent by itself.

 

Anonymous pipes generally do not send data to each other, but only have one flow.

Either the parent process writes to the pipe, and the child process reads from the pipe (1 in the above figure); (At this time, you can turn off the reading end of the parent process and the writing end of the child process, because they will not be used)

Either the child process writes to the pipe, and the parent process reads from the pipe (2 in the figure above). (At this time, you can turn off the reading end of the child process and the writing end of the parent process, because they will not be used)

#include <stdio.h>
#include <unistd.h>
#include <string.h>
//子进程发送数据给父进程,父进程读取到数据后输出
int main()
{
    //在fork之前创建管道
    int pipefd[2];
    int ret = pipe(pipefd);
    if (ret == -1)
    {
        perror("pipe");
        return -1;
    }
 
    //创建子进程
    pid_t pid = fork();
    if (pid > 0)
    {
        printf("parent process,pid=%d\n", getpid());
        //关闭写端
        close(pipefd[1]);
        //父进程 从管道的读取端读取数据
        char buf[1024] = {0};
        while (1)
        {
            //读取数据
            int len = read(pipefd[0], buf, sizeof(buf));
            printf("parent recv :%s,pid=%d\n", buf, getpid());
            bzero(buf,1024);
 
            //写入数据
            //char* str="hello,I am parent";
            //write(pipefd[1],str,strlen(str));
            sleep(1);
        }
    }
    else if (pid == 0)
    {
        //子进程
        printf("child process,pid=%d\n", getpid());
        //关闭读端
        close(pipefd[0]);
        //char buf[1024]={0};
        while (1)
        { //向管道的写入端写入数据
            char *str = "hello,I am child";
            write(pipefd[1], str, strlen(str));
            sleep(1);
 
            //读取数据
            //read(pipefd[0],buf,sizeof(buf));
            //printf("child recv :%s,pid=%d\n", buf, getpid());
            //bzero(buf,1024);
        }
    }
    return 0;
}

Case: Implementing ps aux | grep xxx

program:

/*
    实现 ps aux | grep xxx  父子进程间通信

    子进程:ps aux ,子进程将数据发送给父进程

    父进程:获取到数据,过滤(过滤暂未实现)

    pipe()创建管道
    execlp()执行ps命令
    子进程将标准输出 stdout_fileno 重定向到管道的写端 dup2()

*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
{
    //创建一个管道
    int fd[2];
    int ret=pipe(fd);
    if(ret==-1)
    {
        perror("pipe");
        return -1;
    }

    //创建子进程
    pid_t pid=fork();
    char buf[1024]={0};
    if(pid>0)
    {
        //父进程
        //关闭写端
        close(fd[1]);

        //读取数据
        int len=-1;
        while((len=read(fd[0],buf,sizeof(buf)))>0)  
        {
            //过滤并输出(这里过滤没有实现)
            printf("%s",buf);
            memset(buf,0,1024);

        }
        
        
    }
    else if(pid==0)
    {
        //子进程
        //关闭读端
        close(fd[0]);
        //文件描述符的重定向  STDOUT_FILENO-》fd[1]
        dup2(fd[1],STDOUT_FILENO); 
        //执行ps aux
        execlp("ps","ps","aux",NULL);
        perror("execlp");//execlp函数执行失败了,这里往下的语句才会执行
        return -1;

    }
    else
    {
        perror("fork");
        return -1;
    }
    

    return 0;
}

 


Reference: "Linux High Concurrency Server Development" 2.13 Anonymous Pipeline Communication Case

Guess you like

Origin blog.csdn.net/m0_38062470/article/details/113827458