一尘不染

如何在命名管道(mkfifo)上执行非阻塞fopen?

linux

如果我有一个程序创建并尝试使用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系统上运行)


阅读 604

收藏
2020-06-02

共1个答案

一尘不染

您可以使用open()管道O_RDONLY | O_NONBLOCK,如果需要C流,可以使用fdopen()。但是,-AFAIK可能存在问题select(),它是为读取而打开的管道fd,它没有编写器,总是为读取做准备,并read()返回0,因此select()将无限期启动。

解决这个问题的一种肮脏的方式是打开管道O_RDWR; 也就是说,至少要有一个编写器(您的C ++程序)。无论如何,这将解决您的问题。

2020-06-02