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é?