file-io posix named-pipes nonblocking fifo

file io - ¿Por qué una apertura de solo lectura de un bloque de tubería con nombre?



file-io posix (1)

Así es como está definido. Desde la página Abrir grupo para la función 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.

He notado un par de rarezas cuando trato con named pipes (FIFOs) bajo varios sabores de UNIX (Linux, FreeBSD y MacOS X) usando Python. El primero, y tal vez el más molesto es que los intentos de abrir un FIFO vacío / inactivo de solo lectura bloquearán (a menos que use os.O_NONBLOCK con el nivel más bajo de la llamada os.open() ). Sin embargo, si lo abro para lectura / escritura, no obtengo ningún bloqueo.

Ejemplos:

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

Solo tengo curiosidad por qué. ¿Por qué el bloque de llamada abierta en lugar de una operación de lectura posterior?

También me he dado cuenta de que un descriptor de archivo no bloqueante puede exhibir comportamientos diferentes en Python. En el caso en que utilizo os.open() con os.O_NONBLOCK para la operación de apertura inicial, un os.read() parece devolver una cadena vacía si los datos no están listos en el descriptor del archivo. Sin embargo, si uso fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK) entonces un os.read genera una excepción ( errno.EWOULDBLOCK )

¿Hay alguna otra bandera establecida por la open() normal open() que no está establecida por mi ejemplo os.open() ? ¿Cómo son diferentes y por qué?