Something very strange is happening when I open FIFOs (named pipes) in Python for writing. Consider what happens when I try to open a FIFO for writing in a interactive interpreter:
>>> fifo_write = open('fifo', 'w')
The above line blocks until I open another interpreter and type the following:
>>> fifo_read = open('fifo', 'r') >>> fifo.read()
I don't understand why I had to wait for the pipe to be opened for reading, but lets skip that. The above code will block until there's data available as expected. However let's say I go back to the first interpreter window and type:
>>> fifo_write.write("some testing data\n") >>> fifo_write.flush()
The expected behavior is that on the second interpreter the call to read
will return and we will see the data on the screen, except that is not happening to me. If I call os.fsync
the following happens:
>>> import os >>> fifo_write.flush() >>> os.fsync(fifo_write.fileno()) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 22] Invalid argument
And the fifo reader is still waiting. However, if I call fifo_writer.close()
then the data is flushed. If I use a shell command to feed the pipe:
$ echo "some data" > fifo
then the reader output is:
>>> fifo_read.read() 'some data\n'
Has anyone experienced this? If so is there a workaround for it? My current OS is Ubuntu 11.04 with Linux 2.6.38.
To create a FIFO(named pipe) and use it in Python, you can use the os. mkfifo(). But mkfifo fails with File exists exception if file already exists. In order to avoid that, you can put it in a try-except block.
To recap, you can use a list as a FIFO queue in Python. If you need quicker enqueue/dequeue functionality, use deque from the collections module. If you need a quicker and thread-safe FIFO queue, use the Queue class from the queue module.
read()
doesn't return until it reaches EOF.
You can try specifying the number of bytes you want read, like read(4)
. This will still block until enough bytes have been written, so the producer must write at least that many bytes and then call flush()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With