在典型的 UNIX 风格中,read(2)
返回 0 字节表示文件结束,这可能意味着:
- 文件中没有更多字节
- 套接字的另一端已关闭连接
- 作者关闭了管道
就你而言,fifo.read()
返回一个空字符串,因为编写器已关闭其文件描述符。
您应该检测到这种情况并跳出循环:
读者.py:
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
示例会话
1号航站楼:
$ python reader.py
Opening FIFO...
<blocks>
第2航站楼:
$ echo -n 'hello' > mypipe
1号航站楼:
FIFO opened
Read: "hello"
Writer closed
$
更新1 - 持续重新开放
您表明您希望继续侦听管道上的写入,大概即使在写入器关闭之后也是如此。
为了有效地做到这一点,您可以(并且应该)利用以下事实:
通常,打开 FIFO 会阻塞,直到另一端也打开为止。
在这里,我添加另一个循环open
和read
环形。这样,一旦管道关闭,代码将尝试重新打开它,这将阻塞,直到另一个编写者打开管道:
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
while True:
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
1号航站楼:
$ python reader.py
Opening FIFO...
<blocks>
第2航站楼:
$ echo -n 'hello' > mypipe
1号航站楼:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
第2航站楼:
$ echo -n 'hello' > mypipe
1号航站楼:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
... 等等。
您可以通过阅读了解更多信息man
管道页面:
- PIPE(7) - Linux 程序员手册 http://man7.org/linux/man-pages/man7/pipe.7.html
- FIFO(7) - Linux 程序员手册 http://man7.org/linux/man-pages/man7/fifo.7.html