fifo - reading in a loop

这一生的挚爱 提交于 2019-12-12 08:25:35

问题


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

  • Getting readline to block on a FIFO

回答1:


A FIFO works (on the reader side) exactly this way: it can be read from, until all writers are gone. Then it signals EOF to the reader.

If you want the reader to continue reading, you'll have to open again and read from there. So your snippet is exactly the way to go.

If you have mutliple writers, you'll have to ensure that each data portion written by them is smaller than PIPE_BUF on order not to mix up the messages.




回答2:


You do not need to reopen the file repeatedly. You can use select to block until data is available.

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

In this example you won't read EOF.



来源:https://stackoverflow.com/questions/17449110/fifo-reading-in-a-loop

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!