2011-08-13 12 views
14

Algo muy extraño está sucediendo cuando abro FIFO (named pipes) en Python para escribir. Considere lo que sucede cuando intento abrir una FIFO para escribir en un intérprete interactivo:¿Cómo escribo correctamente en FIFOs en Python?

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

Los bloques de líneas anteriores hasta que abro otro intérprete y escriba lo siguiente:

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

que no entienden por qué tuve que esperar a que se abriera la tubería para leer, pero salteemos 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 tipo:

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

El comportamiento esperado es que en el segundo intérprete de la llamada a read volverá y vamos a ver los datos en la pantalla, excepto que no es sucediéndome a mí. Si llamo os.fsync ocurre 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 todavía está esperando. Sin embargo, si llamo al fifo_writer.close(), se vacían los datos. Si utilizo un comando 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 esto? Mi sistema operativo actual es Ubuntu 11.04 con Linux 2.6.38.

+1

¿Cómo se creó el fifo? – OneOfOne

+0

use ya sea "os.mkfifo ('fifo')" o en shell "mkfifo fifo" –

+1

'fsync()' en una FIFO no tiene sentido; ninguno de los datos se almacena en el disco (excepto * quizás * en intercambio en situaciones muy extrañas). –

Respuesta

11

read() no regresa hasta que llega a EOF.

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

+0

Gracias por eso, al agregar un argumento al método de "lectura" se resolvió el problema, aún así era necesario aclararlo ... –

+2

@ThiadodeArruda ¿qué argumento exactamente? – n611x007

2

Para evitar la necesidad de enjuagar, abra el archivo sin búfer:

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

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

Por supuesto, debe haber creado el fifo primero con os.mkfifo() o mkfifo en el caparazón, como señaló en un comentario.

Cuestiones relacionadas