这个问题在这里已有答案:
我正在用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;
}
在管道的“写入”端的所有引用都已关闭之前,管道的“读取”端将不会看到文件结束条件。 fork()
递增所有打开文件描述的引用。 pipe(fd)
创建管道时将两个打开的文件描述设置为阻塞模式,因此如果没有任何内容正在写入管道的“写入”端,则管道上“读取”端的读取操作将无限期地被阻止。