如何正确写入Python中的FIFO?
当我在Python中打开FIFO(命名管道)进行写入时,发生了一些非常奇怪的事情。 考虑当我尝试打开一个用于在交互式解释器中编写的FIFO时会发生什么情况:
>>> fifo_write = open('fifo', 'w')
上述行阻止,直到我打开另一个解释器并键入以下内容:
>>> fifo_read = open('fifo', 'r')
>>> fifo.read()
我不明白为什么我必须等待管道打开才能阅读,但让我们跳过这一点。 上述代码将会阻塞,直到有数据可用为止。 但是,让我们回到第一个解释器窗口并输入:
>>> fifo_write.write("some testing datan")
>>> fifo_write.flush()
预期的行为是,在第二个解释器上, read
的调用将返回,并且我们将在屏幕上看到数据,除了这不会发生在我身上。 如果我调用os.fsync
,会发生以下情况:
>>> 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
而fifo读者仍在等待。 但是,如果我调用fifo_writer.close()
那么数据将被刷新。 如果我使用shell命令来提供管道:
$ echo "some data" > fifo
那么读者的输出是:
>>> fifo_read.read()
'some datan'
有没有人经历过这个? 如果是的话,是否有解决方法? 我目前的操作系统是Ubuntu 11.04和Linux 2.6.38。
read()
在到达EOF之前不会返回。
您可以尝试指定要读取的字节数,如read(4)
。 这将仍然阻塞,直到写入足够的字节,所以生产者必须至少写入那么多字节,然后调用flush()
。
为避免冲洗,请不要缓冲地打开文件:
fifo_read = open('fifo', 'r', 0)
这将删除高级缓冲。 数据直接进入操作系统,作为一个fifo,他们永远不会真正写入磁盘,而是直接通过fifo缓冲区传递给读写器,因此您不需要同步。
当然,您应该先在shell中使用os.mkfifo()
或mkfifo
创建fifo,就像您在注释中指出的一样。