← 返回首页
Linux高级程序设计(四十七)
发表时间:2021-11-29 22:59:18
无名管道实现父子进程通信

无名管道可以实现父子进程之间的通信。

利用无名管道实现父子进程之间的通信,通常都是父进程负责创建无名管道,然后再创建子进程,子进程继承父进程的无名管道文件描述符,然后父子进程通过无名管道的读写实现通信。

由于无名管道创建后会给当前进程两个文件描述符,如果是两个完全不相关的进程则无法获得同一个无名管道的文件描述符。所以无名管道只能在具有亲缘关系的进程间通信。

实例:

无名管道实现父子进程通信,子进程负责写入字符串,父进程负责读取字符串。

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

int main(int argc, char *argv[])
{
    int fd_pipe[2];
    pid_t pid;

    if (pipe(fd_pipe) == -1)
    { // 创建无名管道
        perror("error to create pipe:");
    }

    pid = fork(); // 创建进程
    if (pid < 0)
    { // 出错
        perror("error to create process:");
        exit(-1);
    }

    if (pid == 0)
    {   // 子进程
        char buff[128] = "";

        while (1)
        {
            fgets(buff, sizeof(buff), stdin);
            //把最后一个回车符替换为字符串结束符号。
            buff[strlen(buff) - 1] = '\0';
            //往管道写端写数据
            if (write(fd_pipe[1], buff, sizeof(buff)) == -1)
            {
                perror("error to write:");
                exit(1);
            }
        }

    }
    else if (pid > 0)
    {  
        // 父进程
        char str[128] = "";
        while (1)
        {
            // 从管理里读数据
            if (read(fd_pipe[0], str, sizeof(str))==-1)
            {
                perror("error to read:");
                exit(1);
            }
            printf("from son, str=%s\n", str); // 打印数据
        }
    }

    return 0;
}

运行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
hello
from son, str=hello
linux
from son, str=linux
world
from son, str=world