读了一个fifo的最后一行

时间:2010-02-21 15:05:28

标签: c unix fifo

以下是这种情况:某些进程将行写入fifo文件(使用mkfifo创建)。在我的程序中的某个时刻,我想阅读fifo中的最后一行,并丢弃所有其他行。仅当fifo中的行少于一行时,该过程才可能阻止。

我无法想出一个干净的方法来做这个,有什么想法吗?

编辑:写作过程永远不会停止在fifo中写入行,最后一行的意思是我读到fifo时的最后一行。它不一定是EOF。

3 个答案:

答案 0 :(得分:2)

如果主要关注的是读取将阻塞,则将FIFO打开为非阻塞。我假设您知道您在流中寻找的内容,并且之前会放弃所有内容。

当有东西可以读取管道时,您也可以使用类似select()的信息。

答案 1 :(得分:2)

如果我正确理解了您的问题,那么您有另一个流程通过fifo为您的程序提供数据,而新数据会废弃以前收到的所有数据,因此您只对最新的数据感兴趣。

在这种情况下,我的方法是 - 使用fifo syscall的O_NONBLOCK标志为fcntl()的描述符设置非阻塞模式,并使用类似这样的内容:

while (!exit_condition) {
    bytes = read(fd, wrkbuf, sizeof(wrkbuf));  // error handling omitted
    if (0 == bytes && bytes_to_process > 0) {
        process(wrkbuf, bytes_to_process);
        bytes_to_process = 0;
    } else
        bytes_to_process = bytes;
}

答案 2 :(得分:1)

我能想到的唯一方法就是让你的程序(读一读)读取FIFO中的所有信息 - 也就是说,程序中的读指针始终位于管道的末尾。读取消息时,您将其添加到内部消息列表(即队列或类似的东西)。您还将保留指向上次读取的消息的指针。

读取最后一行并丢弃所有其他行,然后就是跟踪指向最后一条消息的过程,如果需要,还可以清除队列。

这里的问题是您的内部队列可能变大,并且您需要对队列和最后的消息指针进行并发控制。我在其自己的线程中有FIFO读取器,除了监听管道之外什么都不做。当有消息进入时,您需要锁定队列,添加新消息并更新最后一条消息指针,然后释放锁定。确保在释放锁之前处理所有可用的传入消息。在执行处理的线程中,您应该锁定队列以对其进行操作。确保您将队列锁定的时间不超过绝对必要,否则您将遇到性能问题。