`getline`挂起但没有关闭管道[1]

时间:2019-04-15 13:45:24

标签: c linux pipe getline

我正在使用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;
}

1 个答案:

答案 0 :(得分:2)

在关闭对管道“写”端的所有引用之前,管道的“读”端将看不到文件结束条件。 fork()递增所有打开的文件描述的引用。 pipe(fd)创建的管道将两个打开的文件描述设置为阻止模式,因此,如果没有写入管道的“写”端,则将无限期地阻止对管道“读”端的读取操作。