我正在使用fork()
和pipe()
编写程序,以使子进程写入管道,而父进程从管道中读取(使用getline()
)。但是如果没有在父进程中关闭pipe[1]
,getline()
会永远挂起。为什么会这样?
我正在使用Ubuntu 18.04 LTS。我阅读了手册,但没有提及为什么getline()
可能会挂在那里。
我的程序的简单越野车版本:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
int fd[2];
char *s = NULL;
size_t n = 0;
int rt;
pipe(fd);
pid_t pid = fork();
if (pid != 0) {
//close(fd[1]); // without this line, getline() hangs
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
while ((rt = getline(&s, &n, stdin)) != -1) {
printf("rt: %d\n", rt);
}
} else {
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
for (int i = 0; i < 10; ++i) {
printf("aaa\n");
}
}
return 0;
}
答案 0 :(得分:2)
在关闭对管道“写”端的所有引用之前,管道的“读”端将看不到文件结束条件。 fork()
递增所有打开的文件描述的引用。 pipe(fd)
创建的管道将两个打开的文件描述设置为阻止模式,因此,如果没有写入管道的“写”端,则将无限期地阻止对管道“读”端的读取操作。