即使写端关闭也从管道中读取

Posted

技术标签:

【中文标题】即使写端关闭也从管道中读取【英文标题】:Read from pipe even if the write end is closed 【发布时间】:2018-09-26 16:05:09 【问题描述】:

我的老师说如果管道的写端关闭,子进程就不能再从管道的读端读取,读取会产生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】:

如你所见,你的老师错了。

当您尝试读取 从损坏的管道,但是当您尝试写入到损坏的管道时。

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

【讨论】:

好的,但是管道的手册页说“如果引用管道写入端的所有文件描述符都已关闭,那么从管道读取的尝试将看到文件结束”,但是当我在管道关闭后调用 read 时,我仍然得到剩余的字符而不是 EOF,所以只有当管道为空时我才会得到 EOF,因此即使它的每个写端都关闭,我也可以读取所有管道? 是的,你得到了所有已经写入的数据。否则,写入过程需要以某种方式神奇地“知道”客户端何时完成阅读。

以上是关于即使写端关闭也从管道中读取的主要内容,如果未能解决你的问题,请参考以下文章

FFmpeg - 通过管道输入原始帧 - FFmpeg不检测管道关闭

如何写入命名管道而不等待读取管道

linux中有名管道与匿名管道的实现

linux中有名管道与匿名管道的实现

IPC - 命名管道(fifo)- 使用

IPC - 命名管道(fifo)- 使用