我想在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()
的调用会阻止我的父进程,直到子进程在管道的另一端写入,但我无法解释这种行为。任何提示?
答案 0 :(得分:3)
read
将阻塞,直到至少有一个字节要读取,或者遇到错误,或者它到达流的末尾。当至少有一个字节要读取时,它将尽可能多地读取字节数(最多为您指定的最大数量),然后返回。
在这种情况下,父进程对read
的调用将会阻止,直到子进程write
对管道进行处理。
来自man 7 pipe
部分管道和FIFO上的I / O :
如果进程尝试从空管道读取,则read(2)将阻塞,直到数据可用。如果进程尝试写入完整管道(见下文),则写入(2)块,直到从管道读取足够的数据以允许写入完成。通过使用fcntl(2)F_SETFL操作来启用O_NONBLOCK打开文件状态标志,可以实现非阻塞I / O.