Подтвердить что ты не робот

Почему открыт только для чтения именованный блок?

Я заметил пару странностей при работе с именованными каналами (FIFO) под различными вариантами UNIX (Linux, FreeBSD и MacOS X) с использованием Python. Первое и, возможно, наиболее раздражает то, что попытки открыть пустой/незанятый 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. В случае, когда я использую 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()? Как они отличаются и почему?

4b9b3361

Ответ 1

Это точно так, как оно определено. На странице "Открыть группу" для функции 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.