65

在使用 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()如果文件描述符上的数据尚未准备好,则 an 似乎返回一个空字符串。但是,如果我使用fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK)thenos.read会引发异常 ( errno.EWOULDBLOCK)

是否有一些其他标志open()由我的os.open()示例未设置的正常设置?它们有何不同,为什么?

4

1 回答 1

83

这就是它的定义方式。从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.
于 2011-04-25T20:16:00.817 回答