`getline` 在没有关闭管道 [1] 的情况下挂起
`getline` hangs without closing pipe[1]
我正在用 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;
}
管道的 "read" 端将不会出现文件结束条件,直到对管道 "write" 端的所有引用都已关闭。 fork()
递增所有打开文件描述的引用。 pipe(fd)
创建管道时将两个打开的文件描述设置为阻塞模式,因此如果没有任何内容写入管道的 "write" 端,则对管道 "read" 端的读取操作将被无限期封锁。
我正在用 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;
}
管道的 "read" 端将不会出现文件结束条件,直到对管道 "write" 端的所有引用都已关闭。 fork()
递增所有打开文件描述的引用。 pipe(fd)
创建管道时将两个打开的文件描述设置为阻塞模式,因此如果没有任何内容写入管道的 "write" 端,则对管道 "read" 端的读取操作将被无限期封锁。