2013-07-03 10 views
7

Desidero utilizzare os.mkfifo per la comunicazione semplice tra i programmi. Ho un problema con la lettura dal fifo in un ciclo.fifo - lettura in loop

Consideriamo questo esempio di giocattolo, dove ho un lettore e uno scrittore che lavorano con la fifo. Voglio essere in grado di eseguire il lettore in un ciclo per leggere tutto ciò che entra nel fifo.

# reader.py 
import os 
import atexit 

FIFO = 'json.fifo' 

@atexit.register 
def cleanup(): 
    try: 
     os.unlink(FIFO) 
    except: 
     pass 

def main(): 
    os.mkfifo(FIFO) 
    with open(FIFO) as fifo: 
#  for line in fifo:    # closes after single reading 
#  for line in fifo.readlines(): # closes after single reading 
     while True: 
      line = fifo.read()   # will return empty lines (non-blocking) 
      print repr(line) 

main() 

E lo scrittore:

# writer.py 
import sys 

FIFO = 'json.fifo' 


def main(): 
    with open(FIFO, 'a') as fifo: 
     fifo.write(sys.argv[1]) 

main() 

Se corro python reader.py e poi python writer.py foo, "foo" verrà stampato, ma il FIFO sarà chiuso e il lettore uscirà (o rotazione all'interno del ciclo while). Voglio che il lettore rimanga nel ciclo, così posso eseguire lo scrittore molte volte.

Modifica

Io uso questo frammento di trattare la questione:

def read_fifo(filename): 
    while True: 
     with open(filename) as fifo: 
      yield fifo.read() 

ma forse c'è un modo più ordinato di gestire la cosa, anziché ripetutamente aprire il file ...

Related

risposta

2

Un FIFO lavora (sul lato del lettore) esattamente in questo modo: può essere letto da, fino a quando tutti gli scrittori sono andati. Quindi segnala EOF al lettore.

Se vuoi che il lettore continui a leggere, dovrai aprire nuovamente e leggere da lì. Quindi il tuo frammento è esattamente la strada da percorrere.

Se si dispone di scrittori più piccoli, è necessario assicurarsi che ogni porzione di dati scritta da loro sia inferiore a PIPE_BUF per non confondere i messaggi.

+0

Suppongo che per molti scrittori dovrei usare qualcosa di più stravagante, perché qui gli scrittori si chiudevano l'un l'altro i FIFO? E i dati di uno scrittore potrebbero essere mescolati con i dati dell'altro autore –

+0

Non si chiudono tra loro e se i dati scritti sono abbastanza piccoli, anche loro non interferiscono. Esiste una costante 'PIPE_BUF' che ti dice quanto possono diventare grandi i pacchetti di dati senza interferire l'un l'altro. – glglgl

1

Non è necessario riaprire il file ripetutamente. È possibile utilizzare select per bloccare finché i dati non sono disponibili.

with open(FIFO_PATH) as fifo: 
    while True: 
     select.select([fifo],[],[fifo]) 
     data = fifo.read() 
     do_work(data) 

In questo esempio non si legge EOF.