首页 > 解决方案 > 使用管道在父子之间进行通信

问题描述

为了更好地理解管道在 C 中的工作原理,我决定创建一个简单的程序。它应该做以下事情:首先,我分叉程序。然后父级从标准输入读取并将所有内容写入管道,直到到达 EOF。然后子进程从该管道读取并将内容写回另一个管道,然后应该由父进程读取并写入标准输出。

是的,该程序不是很“有用”,但我只是想让自己熟悉管道以及如何使用它们。这是我的代码:

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

int main(int argc, char **argv) {
    char buf;
    int pipe_one[2];
    int pipe_two[2];
    pid_t child;

    if(pipe(pipe_one) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    if(pipe(pipe_two) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    child = fork();
    switch (child) {
        case -1:
            fprintf(stderr, "Error while forking.\n");
            break;
        case 0:
            // child
            // close unnecessary ends
            close(pipe_one[1]);
            close(pipe_two[0]);

            // read input from parent and write it into pipe
            while(read(pipe_one[0], &buf, 1) > 0) {
                write(pipe_two[1], &buf, 1);
            }
            write(pipe_two[1], "\n", 1);
            close(pipe_one[0]);
            close(pipe_two[1]);
            break;
        default:
            // parent
            // close unnecessary ends
            close(pipe_one[0]);
            close(pipe_two[1]);

            // read from standard input and write it into pipe
            while(read(STDIN_FILENO, &buf, 1) > 0) {
                write(pipe_one[1], &buf, 1);
            }
            write(pipe_one[1], "\n", 1);
            close(pipe_one[1]);

            // wait for child process to finish
            wait(NULL);

            // read from pipe that child wrote into
            while(read(pipe_two[0], &buf, 1) > 0) {
                write(STDOUT_FILENO, &buf, 1);
            }
            write(STDOUT_FILENO, "\n", 1);
            close(pipe_two[0]);
            break;
    }

    exit(EXIT_SUCCESS);
}

预期行为:一开始,程序会读取用户输入,直到到达 EOF,然后将所有内容再次输出到标准输出中。

实际行为:程序读取整个输入,但一旦到达 EOF,它就会终止(成功)而不向标准输出写入任何内容。我究竟做错了什么?如果有人可以查看并帮助我,我会很高兴。

标签: cpipeforkposix

解决方案


你在你的孩子中为你的父母关闭管道。

while(read(pipe_one[0], &buf, 1) > 0) {
                write(pipe_two[1], &buf, 1);
            }
write(pipe_two[1], "\n", 1);
close(pipe_one[0]); // Here you close pipes
close(pipe_two[1]); // for your parent

所以父母不能收到任何东西。只需删除这两行即可。


推荐阅读