1

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

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

编辑:写入过程将永远不会停止将行写入fifo,我的意思是最后一行是我读取fifo时的最后一行。它后面不一定跟着 EOF。

4

3 回答 3

2

如果我正确理解了您的问题,那么您有另一个进程通过 向您的程序提供数据fifo,并且新数据会废弃任何以前收到的数据,因此您只对可用的最新数据感兴趣。

在这种情况下,我的方法是-使用系统调用的标志为fifo' 描述符设置非阻塞模式,并使用如下内容:O_NONBLOCKfcntl()

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;
}
于 2010-02-21T20:49:05.720 回答
2

如果您主要担心读取会阻塞,则将 FIFO 打开为非阻塞。我假设你知道你在流中寻找什么,并且会简单地丢弃之前的所有内容。

您还可以使用诸如select()之类的东西来通知当有什么东西要从管道中读取时。

于 2010-02-21T15:41:13.763 回答
1

我能想到的唯一方法是让你的程序(一次读取)读取 FIFO 中的所有信息——也就是说,程序中的读取指针始终位于管道的末尾。当一条消息被读取时,您会将它添加到消息的内部列表中(即队列或类似的东西)。您还将维护指向最后一条消息的指针。

那么,读取最后一行并丢弃所有其他行只是跟随指针指向最后一条消息的过程,如果需要,清除队列。

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

于 2010-02-21T15:19:22.910 回答