2013-07-03 301 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。