即使写入结束也从管道读取

1 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;
}
Run Code Online (Sandbox Code Playgroud)

5秒后stdout上的输出是foo.所以我理解的是关闭写端只是在已经存在的字符之后添加EOF并且不会在任何即将到来的读取上发送EOF(因此孩子可以读取已经发送的所有字符).我对吗 ?

Uni*_*rsE 5

你发现了,你的老师错了.

你没有得到一个破管"错误"(这实际上是一个信号的组合,SIGPIPE和一个错误EPIPE如果被忽略),当您尝试读取从破裂的管道,但是当你试图一个破裂的管道.

对于Linux系统,您可以在此处阅读更多相关信息,或者您可以查看BSD手册页管道(2).

  • 是的,您将获得已编写的所有数据.否则,当客户端完成阅读时,写作过程需要以某种方式神奇地"知道". (3认同)