为什么命名管道的只读打开会阻塞?

发布于 2024-11-03 17:01:06 字数 1019 浏览 3 评论 0原文

在使用 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 中的示例,使更广泛的受众更容易复制和理解)。

我只是好奇为什么。为什么 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)

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

I've noticed a couple of oddities when dealing with named pipes (FIFOs) under various flavors of UNIX (Linux, FreeBSD and MacOS X) using Python. The first, and perhaps most annoying is that attempts to open an empty/idle FIFO read-only will block (unless I use os.O_NONBLOCK with the lower level os.open() call). However, if I open it for read/write then I get no blocking.

Examples:

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

Note: The behavior is NOT Python specific. Example in Python to make it easier to replicate and understand for a broader audience).

I'm just curious why. Why does the open call block rather than some subsequent read operation?

Also I've noticed that a non-blocking file descriptor can exhibit two different behaviors in Python. In the case where I use os.open() with the os.O_NONBLOCK for the initial opening operation, then an os.read() seems to return an empty string if data is not ready on the file descriptor. However, if I use fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK) then an os.read raises an exception (errno.EWOULDBLOCK)

Is there some other flag being set by the normal open() that's not set by my os.open() example? How are they different and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一桥轻雨一伞开 2024-11-10 17:01:06

这就是它的定义方式。从 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.

That's just the way it's defined. From the Open Group page for the open() function

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文