2010-02-21 79 views
1

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

我不能想出一个干净的方式来做到这一点,任何想法?

编辑:写入过程将永远不会停止写行到FIFO,我的意思是最后一行是最后一次我读了fifo。它不一定跟随EOF。

+0

你说的意思是什么”最后一行“? 'pipe'(又名'fifo')是一个流,而不是一个文件,读取这条线你不知道它是最后一个还是稍后会有更多的数据可用。 – qrdl 2010-02-21 15:19:59

+0

写入过程写入管道的最后一行是最新的信息。这就是为什么当我汇集信息时,我想要最新的。 – Ben 2010-02-21 16:03:40

回答

2

如果您主要关心的是读取会阻塞,然后打开FIFO作为非阻塞。我假设你知道你在流中寻找什么,并且会在之前丢弃所有的东西。

您还可以使用类似select()这样的东西来获知有什么需要读取管道的信息。

1

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

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

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

2

如果我正确理解你的问题,你有另一个进程为你的程序提供数据通过fifo,并且新数据过时了以前收到的任何数据,因此你只关心最新的数据。

在这种情况下,我的办法是 - 设定无阻塞的fifo模式“使用O_NONBLOCK标志fcntl()系统调用S标记,而使用这样的:

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; 
} 
+0

谢谢,这是我最终做的.. – Ben 2010-02-21 21:04:16

相关问题