【发布时间】:2012-07-20 22:01:04
【问题描述】:
给定以下代码:
int main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Child reads from pipe */
close(pipefd[1]); /* Close unused write end */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else { /* Parent writes argv[1] to pipe */
close(pipefd[0]); /* Close unused read end */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
exit(EXIT_SUCCESS);
}
return 0;
}
每当子进程想要从管道中读取数据时,它必须首先关闭管道的一侧以防止写入。当我从子进程的if 中删除该行close(pipefd[1]); 时,
我基本上是在说“好吧,孩子可以从管道中读取,但我允许父级同时写入管道”?
如果是这样,当管道为读写打开时会发生什么?没有互斥?
【问题讨论】:
-
Read() 和 write() 到管道保证是原子的。 (最大 PIPE_BUFF 大小)。这意味着:先到先得。写/读部分将交错,但它们的边界仍然完好无损。
-
如果你不关闭孩子的管道写端,孩子将永远不会看到 EOF,因为只有在所有用户都关闭了写端时才会出现 EOF。有关示例,请参见 stackoverflow.com/questions/7868018/…。