`getline`挂起而没有关闭管道[1] [重复]

问题描述 投票:1回答: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;
}
c linux pipe getline
1个回答
2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.