c read()管道保持空闲状态

时间:2012-03-28 14:21:09

标签: c stdout pipe stdin

我写了这段代码,它应该通过函数将STDOUT上写的东西重定向到STDIN,以便它可以被另一个函数读取。我无法访问这些功能,所以这是我可以使用它们的唯一方法。 mpz_fput(stdout, c)是这些功能之一。它只是打印在c数据结构中包含的STDOUT中。

现在一切正常,在调试之前就像下面的代码一样,我有一个printf();后跟一个fflush(stdout);(需要打印调试消息)。 现在我删除了这两行,我注意到(使用gdb)这段代码在read()函数(这段代码的最后一行)上保持空闲状态

char buffer[BUFSIZ] = "";
int out_pipe[2];
int in_pipe[2];
int saved_stdout;
int saved_stdin;
int errno;

// REDIRECT STDIN
saved_stdin = dup(STDIN_FILENO);    /* save stdin for later */
if(errno= pipe(in_pipe) != 0 ) {          /* make a pipe */
  printf("\n%s",strerror(errno));
  exit(1);
}
close(STDIN_FILENO);
dup2(in_pipe[0], STDIN_FILENO);     /* redirect pipe to stdin */

// REDIRECT STDOUT
saved_stdout = dup(STDOUT_FILENO);  /* save stdout for display later */
if(errno= pipe(out_pipe) != 0 ) {          /* make a pipe */
  printf("\n%s",strerror(errno));
  exit(1);
}
dup2(out_pipe[1], STDOUT_FILENO);   /* redirect stdout to the pipe */
close(out_pipe[1]);

mpz_fput(stdout,c);         // put c on stdout
read(out_pipe[0], buffer, BUFSIZ);  // read c from stdout pipe into buffer

任何想法为什么会这样?

1 个答案:

答案 0 :(得分:0)

似乎你使用了阻止类型。在这种情况下,out_pipe [0]是一个阻塞句柄。因此read()被阻止,并等待out_pipe [0]中的任何内容。

此外,我认为与fflush()有关:

  

对于输出流,fflush()强制写入所有用户空间缓冲数据          对于给定的输出或更新流,通过流的底层写入          功能。对于输入流,fflush()会丢弃所​​有缓冲数据          已从底层文件中获取,但尚未被应用程序获取。          流的打开状态不受影响。

在您的情况下,您将管道重定向到STDOUT,然后调用fflush()以使STDOUT中的所有内容都被刷新并将它们移动到read()缓冲区。然后你调用read()来读出它们。如果你没有调用fflush(),那么read()缓冲区将为空。由于它是read()使用的阻塞句柄,因此无法从缓冲区中读取任何内容,因此它将被阻止。

这是一个简短的理论,我建议你阅读Linux手册页了解更多细节。