【发布时间】:2011-08-12 13:00:31
【问题描述】:
在使用 Python 处理各种风格的 UNIX(Linux、FreeBSD 和 MacOS X)下的命名管道 (FIFO) 时,我注意到了一些奇怪的地方。第一个,也许是最烦人的是尝试打开一个空/空闲 FIFO 只读将阻塞(除非我使用 os.O_NONBLOCK 和较低级别的 os.open() 调用)。但是,如果我打开它进行读/写,那么我不会被阻塞。
例子:
f = open('./myfifo', 'r') # Blocks unless data is already in the pipe
f = os.open('./myfifo', os.O_RDONLY) # ditto
# Contrast to:
f = open('./myfifo', 'w+') # does NOT block
f = os.open('./myfifo', os.O_RDWR) # ditto
f = os.open('./myfifo', os.O_RDONLY|os.O_NONBLOCK) # ditto
我只是好奇为什么。为什么 open 调用阻塞而不是一些后续的读取操作?
我还注意到,非阻塞文件描述符在 Python 中会表现出不同的行为。在我使用os.open() 和os.O_NONBLOCK 进行初始打开操作的情况下,如果文件描述符上的数据尚未准备好,os.read() 似乎会返回一个空字符串。但是,如果我使用 fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK),那么 os.read 会引发异常 (errno.EWOULDBLOCK)
我的os.open() 示例中没有设置普通open() 设置的其他标志吗?它们有何不同?为什么?
【问题讨论】:
-
我建议删除 Python 引用并可能更改此问题的标题。我在处理 Python/C++ 混合项目时碰巧遇到了这个问题,但这绝对不是 Python 的错。就我而言,我试图在 C++ 中创建一个 fifo,然后从 Python 连接到它。自从 C++ 代码挂起后,我从未走到那一步。
-
要在尝试打开文件之前检查文件是否为 fifo(命名管道),(例如,如果您需要排除它)您可以通过以下方式确定:stackoverflow.com/questions/8558884/…
-
第三个语句是错误的(至少在 python3.7 中):open('myfifo', 'w+') 会引发错误:“文件不可搜索”。只有最后 2 个语句有效。
标签: file-io posix named-pipes nonblocking fifo