如何在 Python 中正确写入 FIFO?

发布于 2024-11-29 18:46:46 字数 1105 浏览 2 评论 0原文

当我在 Python 中打开 FIFO(命名管道)进行写入时,发生了一些非常奇怪的事情。考虑一下当我尝试打开 FIFO 以在交互式解释器中进行写入时会发生什么:

>>> fifo_write = open('fifo', 'w')

上面的行会阻塞,直到我打开另一个解释器并键入以下内容:

>>> fifo_read = open('fifo', 'r')
>>> fifo.read()

我不明白为什么我必须等待管道打开进行读取,但让我们跳过这个。上面的代码将阻塞,直到有预期的可用数据为止。然而,假设我回到第一个解释器窗口并输入:

>>> fifo_write.write("some testing data\n")
>>> 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 data\n'

有人经历过这种情况吗?如果是这样,有解决方法吗?我当前的操作系统是 Ubuntu 11.04 和 Linux 2.6.38。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空气里的味道 2024-12-06 18:46:46

read() 在到达 EOF 之前不会返回。

您可以尝试指定要读取的字节数,例如 read(4)。这仍然会阻塞,直到写入足够的字节,因此生产者必须至少写入那么多字节,然后调用flush()

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().

·深蓝 2024-12-06 18:46:46

为了避免刷新的需要,请在不缓冲的情况下打开文件:

fifo_read = open('fifo', 'r', 0)

这将删除高级缓冲。数据直接进入操作系统,并且作为 fifo,它们永远不会真正写入磁盘,而是通过 fifo 缓冲区直接传递到读取器,因此您不需要同步。

当然,您应该首先在 shell 中使用 os.mkfifo() 或 mkfifo 创建 fifo,正如您在注释中指出的那样。

To avoid the need for flushing, open the file without buffering:

fifo_read = open('fifo', 'r', 0)

That will remove high-level buffering. Data go to the OS directly and, being a fifo, they never get actually written to disk but passed straight to the reader thru the fifo buffer, so you don't need to sync.

Of course, you should have created the fifo first with os.mkfifo() or mkfifo at the shell, as you pointed in a comment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文