Pitone - semplici righe di lettura da un tubo
-
12-09-2019 - |
Domanda
Sto cercando di leggere le linee da un tubo ed elaborarli, ma sto facendo qualcosa di sciocco e non riesco a capire cosa. Il produttore sta per continuare a produrre linee a tempo indeterminato, in questo modo:
producer.py
import time
while True:
print 'Data'
time.sleep(1)
Il consumatore deve solo verificare la presenza di linee periodicamente:
consumer.py
import sys, time
while True:
line = sys.stdin.readline()
if line:
print 'Got data:', line
else:
time.sleep(1)
Quando eseguo questo nella shell di Windows come python producer.py | python consumer.py
, solo che dorme per sempre (non sembra mai ottenere i dati?) Sembra che forse il problema è che il produttore non termina, dal momento che se mando una quantità limitata di dati di allora funziona bene.
Come posso ottenere i dati da ricevere e presentarsi per il consumatore? In applicazione reale, il produttore è un programma C ++ non ho alcun controllo.
Soluzione
Alcune vecchie versioni di tubi di Windows simulati attraverso i file (quindi erano inclini a questo tipo di problemi), ma che non è stato un problema in 10+ anni. Prova ad aggiungere un
sys.stdout.flush()
al produttore dopo la print
, e anche provare a fare stdout del produttore unbuffered (utilizzando python -u
).
Naturalmente questo non aiuta se non si ha il controllo del produttore -. Se si tampona troppo della sua produzione si sta ancora andando ad aspettare molto tempo
Purtroppo - mentre ci sono molti approcci per risolvere il problema su sistemi operativi Unix-like, come pyexpect, pexpect , exscript , e paramiko , dubito che qualcuno di loro funziona su Windows; se questo è davvero il caso, mi piacerebbe provare Cygwin , che mette abbastanza di un rivestimento Linux come su Windows come per consentire spesso l'uso di approcci simili a Linux su una macchina Windows.
Altri suggerimenti
Si tratta di I / O che è bufferized di default con Python. Passare l'opzione -u
all'interprete per disattivare questo comportamento:
python -u producer.py | python consumer.py
Si risolve il problema per me.