命名管道不会阻塞

时间:2015-07-01 09:15:39

标签: python linux python-3.x

我正在尝试使用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'然后无限地打印''(空字符串)。

为什么会发生这种情况,我该怎么办呢?

2 个答案:

答案 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='')