简体   繁体   中英

Named pipe won't block

I'm trying to make multiple program communicate using Named Pipes under python.

Here's how I'm proceeding :

import os

os.mkfifo("/tmp/p")
file = os.open("/tmp/p", os.O_RDONLY)

while True:
    line = os.read(file, 255)
    print("'%s'" % line)

Then, after starting it I'm sending a simple data through the pipe :

echo "test" > /tmp/p

I expected here to have test\\n showing up, and the python blocks at os.read() again.

What is happening is python to print the 'test\\n' and then print '' (empty string) infinitely.

Why is that happening, and what can I do about that ?

From http://man7.org/linux/man-pages/man7/pipe.7.html :

If all file descriptors referring to the write end of a pipe have been closed, then an attempt to read(2) from the pipe will see end-of-file

From https://docs.python.org/2/library/os.html#os.read :

If the end of the file referred to by fd has been reached, an empty string is returned.

So, you're closing the write end of the pipe (when your echo command finishes) and Python is reporting that as end-of-file.

If you want to wait for another process to open the FIFO, then you could detect when read() returns end-of-file, close the FIFO, and open it again. The open should block until a new writer comes along.

As an alternative to user9876's answer you can open your pipe for writing right after creating it, this allows it to stay open for writing at all times.

Here's an example contextmanager for working with pipes:

@contextlib.contextmanager
def pipe(path):
    try:
        os.mkfifo(path)
    except FileExistsError:
        pass

    try:
        with open(path, 'w'):  # dummy writer
            with open(path, 'r') as reader:
                yield reader
    finally:
        os.unlink(path)

And here is how you use it:

with pipe('myfile') as reader:
    while True:
        print(reader.readline(), end='')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM