español book python pipe producer-consumer

python - book - django



Python-líneas de lectura simples de una tubería (2)

Estoy tratando de leer líneas de una tubería y procesarlas, pero estoy haciendo algo tonto y no puedo entender qué. El productor seguirá produciendo líneas indefinidamente, así:

productor.py

import time while True: print ''Data'' time.sleep(1)

El consumidor solo necesita revisar las líneas periódicamente:

consumidor.py

import sys, time while True: line = sys.stdin.readline() if line: print ''Got data:'', line else: time.sleep(1)

Cuando ejecuto esto en el shell de Windows como python producer.py | python consumer.py python producer.py | python consumer.py , solo duerme para siempre (¿nunca parece obtener datos?) Parece que tal vez el problema es que el productor nunca termina, ya que si envío una cantidad finita de datos, entonces funciona bien.

¿Cómo puedo obtener los datos para recibirlos y mostrarlos al consumidor? En la aplicación real, el productor es un programa C ++ sobre el que no tengo control.


Algunas versiones antiguas de Windows simularon tuberías a través de archivos (por lo que eran propensos a tales problemas), pero eso no ha sido un problema en más de 10 años. Intenta agregar un

sys.stdout.flush()

al productor después de la print , y también tratar de hacer que el stdout del productor sea sin búfer (usando python -u ).

Por supuesto, esto no ayuda si no tiene control sobre el productor; si amortigua demasiado su producción, todavía va a esperar mucho tiempo.

Desafortunadamente, si bien existen muchos enfoques para resolver ese problema en sistemas operativos similares a Unix, como pyexpect, pexpect , exscript y paramiko , dudo que alguno de ellos funcione en Windows; si ese fuera el caso, probaría Cygwin , que coloca una apariencia de Linux en Windows como para permitir el uso de enfoques similares a Linux en una caja de Windows.


Se trata de la E / S que se almacena en búfer de forma predeterminada con Python. Pase la opción -u al intérprete para deshabilitar este comportamiento:

python -u producer.py | python consumer.py

Me soluciona el problema.