11

I want to use os.mkfifo for simple communication between programs. I have a problem with reading from the fifo in a loop.

Consider this toy example, where I have a reader and a writer working with the fifo. I want to be able to run the reader in a loop to read everything that enters the 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()

And the writer:

# writer.py
import sys

FIFO = 'json.fifo'


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

main()

If I run python reader.py and later python writer.py foo, "foo" will be printed but the fifo will be closed and the reader will exit (or spin inside the while loop). I want reader to stay in the loop, so I can execute the writer many times.

Edit

I use this snippet to handle the issue:

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

but maybe there is some neater way to handle it, instead of repetitively opening the file...

Related

4

2 回答 2

6

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

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

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

于 2017-08-17T23:58:56.077 回答
4

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

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

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

于 2013-07-03T13:46:55.777 回答