非阻塞FIFO:如何检测读者是否存在?

5

我已经创建了一个FIFO,可以通过以下方式进行非阻塞写入:

// others, searching for a non-blocking FIFO-writer may copy this ;-)
mkfifo("/tmp/myfifo", S_IRWXU);
int fifo_fd = open("/tmp/myfifo", O_RDWR);
fcntl(fifo_fd, F_SETFL, fcntl(fifo_fd, F_GETFL) | O_NONBLOCK);

// and then in a loop:
LOGI("Writing into fifo.");
if (write(fifo_fd, data, count) < 0) {
    LOGE("Failed to write into fifo: %s", strerror(errno));
}

非阻塞写入工作得非常好。
另一方面,我打开FIFO进行读取,并执行相同的fcntl()使read()非阻塞。
现在,如果有读者附加,我想在写入端进行多个(CPU密集型)计算。
因此,我需要在写入端找到一种方法,以检测是否在其他地方打开了FIFO进行读取。
有没有人有办法实现这个目标?

你的标题写作者,你的问题却是读者。 - Oliver Charlesworth
"你的头衔写着作家",是的,谢谢。 - Martin L.
为什么不使用 open("fifo", O_WRONLY | O_NONBLOCK) 呢?如果没有读取器,这将失败并显示 ENXIO - melpomene
因为写入过程必须绝对独立于读取者,但读取者应该在任何时刻都可以附加(将读取者视为可选监视器)。只有在写入循环中执行open()和close()才能实现这一点。这样做的效率如何?也许它比我想象的要少有害? - Martin L.
好的,试着去测量一下。最重要的部分是,读者可能会在你检查并发现没有读者之后的任何时刻出现。如果写入器知道它必须提供数据,即使它只阻塞一次,读者是否可以阻塞? - Anton Kovalenko
显示剩余2条评论
1个回答

0
我现在想在写入端进行一些(CPU密集型)计算,但仅当有读取器连接时才进行。
为此,您可以简单地创建一个套接字,当消费者连接到它时,执行一些工作并写回。但我认为更好的解决方案是在消费者连接(或打开FIFO)之前准备好计算结果,但如果没有被消耗,您不希望生产者在工作。因此,定义N,即您愿意保持可供消费的工作结果数量,并让生产者(或生产者)在队列大小为N的队列中工作并保存结果,直到其满为止。
您可以使用线程来实现这一点,一个线程监听连接,从队列中弹出并写入消费者,一个或多个生产者线程工作并推送到队列中。或者,您可以使用POSIX消息队列来避免线程头疼。创建一个大小为N的队列,独立的生产者(用不同语言编写的多个进程)可以将其推入队列,直到其满,而多个独立的消费者则从中弹出。

谢谢您的回答。POSIX消息队列确实很有趣。但是我的解决方案是,客户端创建一个小的“控制”文件,由工作进程通过access(..)进行检查。只有在存在至少一个控制文件时才进行计算。 - Martin L.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接