【问题标题】:`getline` hangs without closing pipe[1] [duplicate]`getline`挂起而不关闭管道[1] [重复]
【发布时间】:2019-04-15 13:45:23
【问题描述】:

我正在编写一个带有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】:

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

    【讨论】:

      猜你喜欢
      • 2015-12-07
      • 2012-11-06
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 1970-01-01
      • 2018-01-25
      相关资源
      最近更新 更多