c - `getline` 没有关闭管道就挂起[1]

标签 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;
}

最佳答案

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

关于c - `getline` 没有关闭管道就挂起[1],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55690591/

相关文章:

javascript - 在 node.js 中输出之前更改响应主体

使用 select() 从管道读取时捕获信号

c - 使用包含 'C' 中四位所有可能组合的字符串进行条件语句

c - gstreamer -plugin intstallation 这个错误是什么意思?

java - linux top 命令的内存和 jconsole 堆的使用有很大不同

linux - 如何阅读有关内置 zsh 命令的文档?

c - beej导流管实例讲解

c - 如何从C中的包头数据中获取参与ARP的机器的MAC地址和IP地址?

c - 使用环形缓冲区和 pthread 的生产者 - 消费者

c:计算中使用的赋值