父进程中的read()是否在管道中等待子write()?

时间:2015-10-05 21:57:54

标签: c pipe fork ipc wait

我想在C中使用子编写器和父级读取器之间建立管道。 我认为我的父进程必须等待它的子进程才能在缓冲区中写入,然后我才能检查它,所以我编写了下面这段代码:

pipe(fd);
// ... checks for pipe
pid_t pid = fork();
// ... checks for fork
if (pid == 0) {
    close(fd[0]);
    // Long sleep hoping parent will terminate before the write()
    sleep(10);
    write(fd[1], "hello", strlen("hello") + 1);
    close(fd[1]);
} else {
    close(fd[1]);
    read(fd[0], buf, sizeof(buf));
    printf("received: %s\n", buf);
    close(fd[0]);
}
return 0;

输出意外(或不是?)received: hello。 如果我用for (volatile int i = 0; i < some_big_int; ++i);循环替换对sleep()的调用,则输出相同。 我不认为对read()的调用会阻止我的父进程,直到子进程在管道的另一端写入,但我无法解释这种行为。任何提示?

1 个答案:

答案 0 :(得分:3)

read将阻塞,直到至少有一个字节要读取,或者遇到错误,或者它到达流的末尾。当至少有一个字节要读取时,它将尽可能多地读取字节数(最多为您指定的最大数量),然后返回。

在这种情况下,父进程对read的调用将会阻止,直到子进程write对管道进行处理。

来自man 7 pipe部分管道和FIFO上的I / O

  

如果进程尝试从空管道读取,则read(2)将阻塞,直到数据可用。如果进程尝试写入完整管道(见下文),则写入(2)块,直到从管道读取足够的数据以允许写入完成。通过使用fcntl(2)F_SETFL操作来启用O_NONBLOCK打开文件状态标志,可以实现非阻塞I / O.