我正在尝试使用python下的命名管道进行多个程序通信。
以下是我的处理方式:
import os
os.mkfifo("/tmp/p")
file = os.open("/tmp/p", os.O_RDONLY)
while True:
line = os.read(file, 255)
print("'%s'" % line)
然后,在启动之后,我通过管道发送一个简单的数据:
echo "test" > /tmp/p
我希望此处显示test\n
,而python会再次阻止os.read()
。
正在发生的事情是python打印'test\n'
然后无限地打印''
(空字符串)。
为什么会发生这种情况,我该怎么办呢?
答案 0 :(得分:2)
来自http://man7.org/linux/man-pages/man7/pipe.7.html:
如果引用管道写入端的所有文件描述符都已存在 关闭,然后尝试从管道中读取(2)将看到文件结束
来自https://docs.python.org/2/library/os.html#os.read:
如果已到达fd引用的文件末尾,则返回空字符串。
因此,您正在关闭管道的写入端(当您的echo命令完成时),并且Python正在报告为文件结束。
如果您想等待另一个进程打开FIFO,那么您可以检测read()何时返回文件结束,关闭FIFO并再次打开它。开放应该阻止,直到新作家出现。
答案 1 :(得分:0)
作为user9876's answer的替代方案,您可以在创建后立即打开管道进行书写,这样就可以随时保持打开状态。
以下是使用管道的示例上下文管理器:
@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)
以下是您使用它的方式:
with pipe('myfile') as reader:
while True:
print(reader.readline(), end='')