【问题标题】:Reading from a pipe even after the write end is closed即使在写端关闭后从管道中读取
【发布时间】:2018-07-20 22:05:46
【问题描述】:

您能否解释一下为什么即使在父进程关闭其写入端之后子进程也能够读取?

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

int main()
{
    int fd[2];
    char buffer[20];

    pipe(fd);

    if ( fork() ==  0 ) //child
    {
        close(fd[0]); //As it is writing close the read end
        strcpy(buffer, "Hello World");
        write(fd[1], buffer, sizeof(buffer));
        close(fd[1]);
    }
    else            //parent
    {
        close(fd[1]);   //As it is reading closing the write end
        while(1)
        {
                read(fd[0], buffer, sizeof(buffer));
                printf("Buffer:%s\n", buffer);
                sleep(1);
        }
        close(fd[0]);
    }
}

O/P: Child 连续打印:

Buffer:Hello World

为什么即使父母终止,孩子也能收到? read不应该得到EOF吗?

【问题讨论】:

  • 它没有。随后的读取失败,但您忽略了这一点,并且缓冲区的内容没有改变,因此您一遍又一遍地看到相同的信息......
  • ...为什么你认为它应该终止?
  • 读取返回值后,从第二次开始为“0”。是EOF的意思吗
  • 是的,这就是您在使用 read() 时检测 EOF 的方式。
  • 您有没有费心阅读函数的documentation 以了解它是如何工作的? 如果当前文件偏移位于或超过文件末尾,则不读取任何字节,read() 返回零。

标签: c linux operating-system pipe fork


【解决方案1】:

为什么即使父母终止,孩子也能收到? read不应该得到EOF吗?

此时父进程基本上什么都不读取(即:read() 正在返回 0)并一遍又一遍地打印它在之前调用 read() 时读取的内容。


您必须查看read() 系统调用返回的值。该值的类型为int,基本上是:

  • -1:错误,出了点问题。
  • 0:没有其他内容可阅读,即:EOF(您要查找的内容)。
  • 否则:read() 读取的字节数存储到buffer

您可以相应地重写父级的while-loop:

while(1) {
    int count = read(fd[0], buffer, sizeof(buffer));
    switch (count) {
    case 0: // EOF
        break;
    case -1: // read() error
        // ... error handling ...
        break;
    default: // fine
        // count contains the number of bytes read
        buffer[count] = '\0'; // NUL character, to indicate the end of string
        printf("Buffer:%s\n", buffer);
        sleep(1);  
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多