【问题标题】:c read() with pipe stays idlec read() 与管道保持空闲
【发布时间】:2012-03-28 14:21:08
【问题描述】:

我编写了这段代码,它应该将一个函数在 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

知道为什么吗?

【问题讨论】:

  • 如何调用你的程序?你认为你的read() 会从哪里读取它的数据?
  • mpz_fput 行中的“c”是什么?是否有一个 \n 来刷新它?
  • @Eregrith 我应该说这只是代码的一部分,我只是发布了“有趣的位”,因为它卡在最后一行。这些是以下两行,我将“c”的内容放入外部程序的 STDIN 中:write(in_pipe[1], buffer, strlen(buffer)); //将 c 从缓冲区系统写入标准输入管道(“ep1617/time/ep1617.oracle”); // 调用 oracle
  • @WilliamMorris 是的,mpz_fput() 放在标准输出上的最后一件事是 \n 字符
  • 顺便说一下,错误处理不太正确。 pipe() 不返回错误号。

标签: c stdout pipe stdin


【解决方案1】:

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

此外,我认为 fflush() 有一些关系:

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

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

这是一个简单的理论,我建议你阅读 Linux 手册了解更多详细信息。

【讨论】:

  • 我不明白为什么如果我把 printf();接着是 fflush(stdout);在它之上
猜你喜欢
  • 1970-01-01
  • 2021-04-06
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多