Python打开FIFO永久阻塞

5

我正在尝试使用Python实现命名管道进行IPC,但出现了问题。open会阻塞进程。

import os
path = '/tmp/fifo'
os.mkfifo(path)
fifo = open(path, 'w') # never returns

open(path, 'r') 相同

我哪里做错了?

Python 3.6.1

4个回答

13

我已经想通了。 open 会阻塞,直到管道的另一端打开。

使用 os.open,如果 os.O_NONBLOCK 被设置为标志,则语句将是非阻塞的。非阻塞可能在您的操作系统上无法正常工作。我相信它适用于 Unix 发行版,但不适用于 Windows。


救命的注释。 - Metehan Yıldırım
这个答案太不准确了,因此容易出错。请查看我下面的回答 - teika kazura

0

更正接受的答案,这个答案太不准确,如果不是完全错误的话。以下内容来自Linux的man fifo(7)

首先,阻塞模式打开。这就是OP发现的:

通常情况下,打开FIFO会一直阻塞,直到另一端也被打开。

非阻塞、只读打开的情况是:

进程可以以非阻塞模式打开FIFO。在这种情况下,即使没有人在写端打开,只读打开也会成功。

但是非阻塞、只写打开是危险的:

只写打开会失败,并返回ENXIO(没有这样的设备或地址),除非另一端已经被打开

有一个解决方法,即读写打开。但是这也需要小心处理:

在Linux下,以读写模式打开一个FIFO管道无论是阻塞还是非阻塞都会成功。POSIX对此行为没有明确规定。这可以用来在没有可用的读取者时打开一个FIFO管道进行写入。
手册页中提到了一个实际的注意事项 :)
使用同一连接的两端与自身通信的进程应该非常小心以避免死锁。

-1

函数os.mkfifo(path)创建所需的路径(如果所有文件夹不存在,则构建整个路径)。

因此,您需要像这样添加文件名:fifo = open(path + file, 'r')

通常,FIFO用作“客户端”和“服务器”类型进程之间的会合点:服务器打开FIFO以进行读取,而客户端则打开它以进行写入。请注意,mkfifo()不会打开FIFO——它只创建了会合点


path + file will just concatenate strings, and in my case /tmp defiantly exists, no need to create it. os.mkfifo creates the file successfully ls -latrh /tmp/pipe prw-r--r-- 1 oleg users 0 Oct 3 08:30 /tmp/pipe - Oleg Antonyan

-1
根据 os.mkfifo,你需要使用以下代码: fifo = open(path, dir_fd='w')

不起作用。os.mkfifo(path,dir_fd ='w')抛出TypeError:argument should be integer or None,not str,而dir_fd = os.O_WRONLY则没有。但结果是相同的:open永远阻塞 - Oleg Antonyan
dir_fd 应该是一个文件描述符,读/写标志。 - David Ehrmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接