2010-02-21 57 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