fifo - 循环阅读

时间:2013-07-03 13:18:25

标签: python mkfifo

我想使用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()

但也许有一些更简洁的方法来处理它,而不是重复打开文件......

相关

2 个答案:

答案 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。

相关问题