python linux fifo mkfifo

¿Cómo escribo correctamente a FIFOs en Python?



title in python plot (2)

Algo muy extraño está sucediendo cuando abro FIFOs (canalizaciones con nombre) en Python para escribir. Considere lo que sucede cuando intento abrir un FIFO para escribir en un intérprete interactivo:

>>> fifo_write = open(''fifo'', ''w'')

La línea anterior bloquea hasta que abro otro intérprete y escribo lo siguiente:

>>> fifo_read = open(''fifo'', ''r'') >>> fifo.read()

No entiendo por qué tuve que esperar a que se abriera la tubería para leer, pero vamos a omitir eso. El código anterior se bloqueará hasta que haya datos disponibles como se esperaba. Sin embargo, digamos que vuelvo a la primera ventana de intérprete y escribo:

>>> fifo_write.write("some testing data/n") >>> fifo_write.flush()

El comportamiento esperado es que en el segundo intérprete, la llamada a read volverá y veremos los datos en la pantalla, excepto que eso no me está sucediendo. Si llamo a os.fsync sucede lo siguiente:

>>> import os >>> fifo_write.flush() >>> os.fsync(fifo_write.fileno()) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 22] Invalid argument

Y el lector fifo sigue esperando. Sin embargo, si llamo fifo_writer.close() , los datos se eliminan. Si utilizo un comando de shell para alimentar la tubería:

$ echo "some data" > fifo

entonces la salida del lector es:

>>> fifo_read.read() ''some data/n''

Alguien ha experimentado esto? Si es así, ¿hay una solución para ello? Mi sistema operativo actual es Ubuntu 11.04 con Linux 2.6.38.


Para evitar la necesidad de vaciar, abra el archivo sin almacenamiento en búfer:

fifo_read = open(''fifo'', ''r'', 0)

Eso eliminará el búfer de alto nivel. Los datos van directamente al sistema operativo y, al ser un fifo, nunca se escriben en el disco, sino que se pasan directamente al lector a través del búfer de fifo, por lo que no es necesario sincronizar.

Por supuesto, deberías haber creado el fifo primero con os.mkfifo() o mkfifo en el shell, como mkfifo en un comentario.


read() no vuelve hasta que alcanza EOF.

Puede intentar especificar el número de bytes que desea leer, como read(4) . Esto seguirá bloqueando hasta que se hayan escrito suficientes bytes, por lo que el productor debe escribir al menos tantos bytes y luego llamar a flush() .