2.13匿名管道通信案例

在上一篇程序示例3中,实际上是存在错误的,如在下图中,父进程不仅接收了子进程发送来的数据,有时候也接收了它自己发送的数据。

匿名管道中一般不会相互发送数据,而是只有一个流向。

要么父进程往管道中写,子进程从管道中读(上图中1);(此时,可关闭父进程的读端,子进程的写端,因为它们不会被用到)

要么子进程往管道中写,父进程从管道中读(上图中2)。(此时,可关闭子进程的读端,父进程的写端,因为它们不会被用到)

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

案例:实现 ps aux | grep xxx

程序:

/*
    实现 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;
}


参考:《Linux高并发服务器开发》2.13匿名管道通信案例

猜你喜欢

转载自blog.csdn.net/m0_38062470/article/details/113827458