【问题标题】:fifo - reading in a loopfifo - 循环读取
【发布时间】:2013-07-01 05:01:09
【问题描述】:

我想使用os.mkfifo 进行程序之间的简单通信。我在循环读取 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 循环内旋转)。我希望 reader 留在循环中,所以我可以多次执行 writer。

编辑

我使用这个 sn-p 来处理这个问题:

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

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

相关

【问题讨论】:

    标签: python mkfifo


    【解决方案1】:

    您无需反复重新打开文件。您可以使用 select 来阻止,直到数据可用。

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

    在此示例中,您不会读取 EOF。

    【讨论】:

    【解决方案2】:

    FIFO 的工作方式(在读取器端)正是这样:它可以被读取,直到所有写入器都消失。然后它向阅读器发出 EOF 信号。

    如果您希望阅读器继续阅读,则必须再次打开并从那里阅读。所以你的 sn-p 正是要走的路。

    如果您有多个写入者,则必须确保他们写入的每个数据部分都小于PIPE_BUF,以免混淆消息。

    【讨论】:

    • 我想对于多个写入器我应该使用更花哨的东西,因为这里写入器会关闭彼此的 FIFO?来自一位作家的数据可能会与来自另一位作家的数据混合
    • 它们不会相互关闭,如果写入的数据足够小,它们也不会相互干扰。有一个常量PIPE_BUF,它告诉您数据包在不相互干扰的情况下可能变得多大。
    猜你喜欢
    • 2012-10-11
    • 2017-09-12
    • 2013-05-14
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多