2013-07-03 295 views
7

我想使用os.mkfifo進行程序之間的簡單通信。我在循環中讀取fifo時遇到問題。fifo - 循環讀取

考慮一下這個玩具的例子,我有一個讀寫器和一個使用fifo的作家。我希望能夠在循環中運行讀取器來讀取進入fifo的所有內容。

# reader.py 
import os 
import atexit 

FIFO = 'json.fifo' 

@atexit.register 
def cleanup(): 
    try: 
     os.unlink(FIFO) 
    except: 
     pass 

def main(): 
    os.mkfifo(FIFO) 
    with open(FIFO) as fifo: 
#  for line in fifo:    # closes after single reading 
#  for line in fifo.readlines(): # closes after single reading 
     while True: 
      line = fifo.read()   # will return empty lines (non-blocking) 
      print repr(line) 

main() 

和作者:

# writer.py 
import sys 

FIFO = 'json.fifo' 


def main(): 
    with open(FIFO, 'a') as fifo: 
     fifo.write(sys.argv[1]) 

main() 

如果我運行python reader.py後來python writer.py foo,將印有「富」,但FIFO將被關閉,讀者將退出(或旋while循環內)。我希望讀者留在循環中,所以我可以多次執行作者。

編輯

我用這個片段來處理這個問題:

def read_fifo(filename): 
    while True: 
     with open(filename) as fifo: 
      yield fifo.read() 

但也許有,而不是重複打開文件來處理它的一些更合適的方法,...

相關

回答

2

一個FIFO工作(在讀寫器側)正是這樣:它可以讀取,直到所有的作家都不見了。然後它向讀者發出EOF信號。

如果您希望讀者繼續閱讀,您必須再次打開並閱讀。所以你的片段就是要走的路。

如果您有多個作者,您必須確保他們編寫的每個數據部分小於PIPE_BUF,以免混淆消息。

+0

我想,對於多個作家,我應該使用一些更花哨的東西,因爲這裏的作家會關閉對方的FIFO?並且來自一個作者的數據可能與來自另一個作者的數據混合在一起 –

+0

它們彼此不會關閉,並且如果寫入的數據足夠小,則它們也不會相互干擾。有一個不斷的'PIPE_BUF'告訴你數據包可能變得多大,而不會相互干擾。 – glglgl

1

您不需要重複打開文件。您可以使用select來阻塞,直到數據可用。

with open(FIFO_PATH) as fifo: 
    while True: 
     select.select([fifo],[],[fifo]) 
     data = fifo.read() 
     do_work(data) 

在這個例子中,你不會閱讀EOF。