从管道读取,即使写入端已关闭

时间:2018-09-26 16:05:09

标签: c unix pipe

我的老师说,如果关闭管道的写入端,则子进程将无法再从管道的读取端进行读取,并且读取会产生BROKEN _PIPE错误。但是,在封闭管上阅读时,我无法获得此代码来生成任何错误:

#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main(void) {
    int pipefd[2];
    char c;

    pipe(pipefd);

    if (fork() == 0) {
        close(pipefd[1]);
        sleep(5);
        // The parent has already closed pipefd[1]
        while (read(pipefd[0], &c, 1)) {
            printf("%c", c);
        }
        close(pipefd[0]);
        return 0;
    }

    close(pipefd[0]);

    char str[] = "foo";
    write(pipefd[1], str, 4);

    close(pipefd[1]);

    return 0;
}

5秒后在标准输出上的输出为foo。因此,我的理解是,关闭写入端只是在字符已经存在之后添加EOF,并且不会在即将进行的任何读取中发送EOF(这样孩子就可以读取所有已发送的字符)。我说的对吗?

1 个答案:

答案 0 :(得分:6)

您发现,您的老师是错误的。

当您尝试时,不会出现断线“错误”(实际上是信号SIGPIPE和错误EPIPE的组合,如果忽略了该错误)从破损的管道读取,但是当您尝试写入至破损的管道时。

对于Linux系统,您可以阅读有关此here的更多信息,或者可以查看BSD手册页pipe(2)