【问题标题】:How do I perform a non-blocking fopen on a named pipe (mkfifo)?如何在命名管道 (mkfifo) 上执行非阻塞 fopen?
【发布时间】:2010-10-09 11:07:54
【问题描述】:

如果我有一个程序创建并尝试使用 mkfifo 打开命名管道,我如何打开管道进行读取或写入而不阻塞?

具体来说,我正在编写一个可以使用或不使用 gui(用 Java 编写)运行的 C 程序。

在 C 程序中,我使用 mkfifo 成功创建了命名管道,但是当我这样做时

FILE* in = fopen(PIPE_IN, "r"); /* Where PIPE_IN is the filename*/

在 GUI 打开该管道进行写入之前,fopen 不会返回。我想要做的是让该管道准备好读取一次(如果)GUI决定写入它 - 我将把文件描述符放在 select() 调用中。可以合理地预期 Java GUI 可能永远不会真正启动,因此我不能依赖它在任何特定点打开管道的另一端,甚至根本无法打开。

我还会打开第二个管道进行写作,我想我也会遇到同样的问题。此外,我无法在没有阅读器的输出管道上设置 O_NONBLOCK。

有什么建议吗?

(这是在linux系统上运行的)

【问题讨论】:

  • 是否需要在 select() 在输入管道上触发之前打开输出管道?
  • @tinkertim - 我想技术上不是 - 我已经在设置函数中设置了它们,但我可以先设置输出管道然后调用 select,为什么?

标签: c linux named-pipes blocking fifo


【解决方案1】:

你可以open()你的管道O_RDONLY | O_NONBLOCK,如果你想要C流,你可以用fdopen()得到它。但是,select() 可能存在问题 - AFAIK,为读取而打开的管道 fd 始终准备好读取,而 read() 返回 0,因此 select() 将无限期触发。

解决这个问题的一个笨办法是打开管道O_RDWR;也就是说,至少有一个作家(你的 C++ 程序)。无论如何,这将解决您的问题。

【讨论】:

  • 我会为读者试一试 - 但我不能在输出管道上设置 O_NONBLOCK...
  • POSIX 标准说(of select()):“当使用 O_NONBLOCK 清除对输入函数的调用不会阻塞时,无论该函数是否会传输数据,都应认为描述符已准备好读取成功地。” (POSIX.1:2008)。
  • 在程序读取(或写入)时打开管道 O_RDWR 会导致死锁 - 除非实际上还有另一个进程也打开了管道。
  • @Jonathan Leffler - 但是我可以打开它 RDWR 并轮询它以查看另一个进程何时实际写入它吗?这应该不会导致死锁,对吧?
  • 是的,这应该在 select() 中阻塞。对于管道的写入端没有这样的解决方案,您可以做的最好的事情可能是在收到 Java 程序的一些提示后打开写入端
猜你喜欢
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 2010-10-08
  • 2011-12-05
相关资源
最近更新 更多