我想使用os.mkfifo进行程序之间的简单通信。我在循环中读取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
,则会打印“foo”但会关闭fifo并且读取器将退出(或在while
循环内旋转)。我希望读者留在循环中,这样我就可以执行多次写作了。
修改
我使用此代码段来解决问题:
def read_fifo(filename):
while True:
with open(filename) as fifo:
yield fifo.read()
但也许有一些更简洁的方法来处理它,而不是重复打开文件......
相关
答案 0 :(得分:4)
FIFO(读取器端)正是这样做的:它可以被读取,直到所有的写入器都消失。然后它向读者发出EOF信号。
如果您希望读者继续阅读,您必须再次打开并从那里阅读。所以你的代码片段就是你要走的路。
如果您有多个编写器,则必须确保它们写入的每个数据部分都小于PIPE_BUF
,以免混淆这些消息。
答案 1 :(得分:3)
您无需重复重新打开该文件。您可以使用select来阻止数据可用。
with open(FIFO_PATH) as fifo:
while True:
select.select([fifo],[],[fifo])
data = fifo.read()
do_work(data)
在此示例中,您不会阅读EOF。