在使用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
注意:该行为不是Python特有的。在Python中的例子,使更广泛的受众更容易复制和理解)。
我只是好奇为什么。为什么打开调用阻塞而不是一些随后的读操作?
我还注意到非阻塞文件描述符在Python中可以表现出两种不同的行为。在我使用os.open()
和os.O_NONBLOCK
进行初始打开操作的情况下,如果文件描述符上的数据未准备好,则os.read()
似乎返回空字符串。但是,如果我使用fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK)
,那么os.read
会引发异常(errno.EWOULDBLOCK
)
是否有一些其他的标志是由正常的open()
,而不是由我的os.open()
的例子设置?它们有什么不同,为什么?
它就是这样定义的。open()
函数的Open Group页面
O_NONBLOCK
When opening a FIFO with O_RDONLY or O_WRONLY set: If O_NONBLOCK is
set:
An open() for reading only will return without delay. An open()
for writing only will return an error if no process currently
has the file open for reading.
If O_NONBLOCK is clear:
An open() for reading only will block the calling thread until a
thread opens the file for writing. An open() for writing only
will block the calling thread until a thread opens the file for
reading.