为什么只读打开命名管道块?

Jim*_*nis 57 file-io posix nonblocking named-pipes fifo

在使用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
Run Code Online (Sandbox Code Playgroud)

我只是好奇为什么.为什么打开调用块而不是后续的一些读操作?

另外我注意到非阻塞文件描述符可以表现为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()例子未设置的法线设置?它们有什么不同,为什么?

Jim*_*son 72

这就是它的定义方式.从已公开组页面open()功能

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.
Run Code Online (Sandbox Code Playgroud)

  • 是的,吉姆丹尼斯,你不是唯一被抛出的人.对我来说,这种行为完全没有预料到.我不知道有人能预测这种行为.在这里,我试图只打开管道作为O_WRONLY来编写干净的代码,只是发现它挂起(因此我发现自己在这里.)是的,你应该总是阅读文档,但正如Jim指出的那样,这似乎改变了语义对于特定类的文件描述符,`open`.根本不像Unix那样. (9认同)
  • 这正是我所希望的那种答案(并且可以说是懒得去追捕自己).这似乎是一个特殊的重载open()语义的例子,它与FIFO不同于任何其他类型的文件描述符.我很想从这个问题中删除Python标签,因为我怀疑它根本不是Python特有的; 它恰好是我提供一个我所谈论的例子的最简单方法. (4认同)