【问题标题】:can't read from stream until child exits?在孩子退出之前无法从流中读取?
【发布时间】:2011-02-12 08:50:21
【问题描述】:

好的,我有一个创建两个管道的程序 -> 分叉 -> 子级的标准输入和标准输出被重定向到每个管道的一端 -> 父级连接到管道的另一端并尝试读取关联的流使用孩子的输出并将其打印到屏幕上(我最终也会让它写入孩子的输入)。

问题是,当父级尝试 fgets 子级的输出流时,它只是停止并等待子级死去 fgets 然后打印输出。如果孩子不退出,它就会永远等待。到底是怎么回事?我认为 fgets 可能会阻塞直到 SOMETHING 在流中,但不会一直阻塞直到孩子放弃它的文件描述符。

代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
 FILE* fpin;
 FILE* fpout;
 int input_fd[2];
 int output_fd[2];
 pid_t pid;
 int status;
 char input[100];
 char output[100];
 char *args[] = {"/somepath/someprogram", NULL};
 fgets(input, 100, stdin); // the user inputs the program name to exec

 pipe(input_fd);
 pipe(output_fd);
 pid = fork();

 if (pid == 0) {
  close(input_fd[1]);
  close(output_fd[0]);
  dup2(input_fd[0], 0);
  dup2(output_fd[1], 1);
  input[strlen(input)-1] = '\0';
  execvp(input, args);
 }
 else {
  close(input_fd[0]);
  close(output_fd[1]);
  fpin = fdopen(input_fd[1], "w");
  fpout = fdopen(output_fd[0], "r");
  while(!feof(fpout)) {
   fgets(output, 100, fpout);
   printf("output: %s\n", output);
  }
 }

 return 0;
}

【问题讨论】:

    标签: c stream pipe fork redirect


    【解决方案1】:

    孩子可能应该@987654321@ 其输出,和/或正确终止行。否则 I/O 缓冲会在数据上挂起很长一段时间。

    在移交控制权之前,您可以尝试在子文件的输出文件描述符上设置O_NONBLOCK 标志(使用@987654322@),但这需要您相应地更改您的父代码。正如 cmets 中所指出的,如果孩子使用基于 FILE 的 I/O,这将无法帮助您克服在 C 标准库级别完成的缓冲。

    【讨论】:

    • 嗯,你是对的。当我刷新输出时,它可以工作。问题是,我没有办法控制孩子。我只能用我的测试程序来控制它,因为我可以编辑源代码......我如何确保任何被 execvp'ed 的程序的输出被刷新或非缓冲或其他东西...... arghhh
    • 等等,这里是测试子的代码: printf("Enter input: \n"); fflush(标准输出);如果我取出 /n 或 fflush,它会延迟.. 我需要它在没有 /n 的情况下阅读它,并且.. 没有我 fflushing。
    • 我可能不应该使用 fgets...但不确定是否能解决 fflushing 位。
    • 问题完全出在孩子这边。如果子进程使用的是行缓冲 IO 并且在没有换行符或fflush() 的情况下写入,那么数据永远不会离开子进程 - 没有其他人可以对此做任何事情。
    • @caf:但是孩子的文件描述符是由父母创建的,所以在孩子获得控制权之前可以在上面设置选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多