c read() 管道保持空闲

标签 c stdout pipe stdin

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

现在,在调试时一切正常,就像之前的以下代码一样,我有一个 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

知道为什么吗?

最佳答案

看来您使用了阻止类型。在这种情况下,out_pipe[0] 是一个阻塞句柄。因此 read() 被阻塞,并等待从 out_pipe[0] 输出的任何内容。

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

For output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function. For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been by the application. The open status of the stream is unaffected.

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

这是简要的理论,我建议您阅读 Linux 手册页以获取更多详细信息。

关于c read() 管道保持空闲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9909494/

相关文章:

c - 查看后台进程的输出

c++ - 以最佳方式从 system() 命令捕获标准输出

macos - OS X/Linux : pipe into two processes?

perl - 从 perl 管道运行 "less"

c - 在 html 文档中查找 JavaScript 数组的正则表达式

c++ - 将 C++ 函数名称打印到 C 而不进行修饰

创建新文件,其名称取自变量值

c - 有没有办法在没有 math.h 的情况下解决 c 中底数始终为 2 的未知指数?

Windows API 彩色输出到 Powershell/cmd.exe 中的标准输出

haskell - Haskell 中的管道字符串到 shell 命令