Почему открываемый только для чтения блок именованного канала? - PullRequest
57 голосов
/ 25 апреля 2011

Я заметил несколько странностей, когда имел дело с именованными каналами (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()?Чем они отличаются и почему?

1 Ответ

69 голосов
/ 26 апреля 2011

Так оно и определено. Со страницы Open Group для функции 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.
...