Python - простые строки чтения из трубы
Я пытаюсь читать строки из трубы и обрабатывать их, но я делаю что-то глупое, и я не могу понять, что. Продюсер будет продолжать производить линии на неопределенный срок, например:
producer.py
import time
while True:
print 'Data'
time.sleep(1)
Потребителю просто нужно периодически проверять строки:
consumer.py
import sys, time
while True:
line = sys.stdin.readline()
if line:
print 'Got data:', line
else:
time.sleep(1)
Когда я запускаю это в оболочке Windows как python producer.py | python consumer.py
, он просто спит навсегда (никогда, кажется, не получает данные?) Кажется, что проблема заключается в том, что продюсер никогда не заканчивается, поскольку, если я отправлю конечный объем данных то он отлично работает.
Как я могу получить данные, которые будут получены и отображаться для потребителя? В реальном приложении производитель - это программа на С++, над которой я не контролирую.
Ответы
Ответ 1
Некоторые старые версии Windows моделировали трубы через файлы (поэтому они были склонны к таким проблемам), но это не было проблемой через 10 лет. Попробуйте добавить
sys.stdout.flush()
продюсеру после print
, а также попытайтесь сделать файл stdout производителя небуферизованным (используя python -u
).
Конечно, это не поможет, если у вас нет контроля над продюсером - если он слишком сильно загружает свой результат, вы все равно будете долго ждать.
К сожалению, хотя существует много подходов к решению этой проблемы в Unix-подобных операционных системах, таких как pyexpect, pexpect, exscript и paramiko, я сомневаюсь, что любой из них работает в Windows; если это действительно так, я бы попробовал Cygwin, что накладывает на Linux достаточно похожего шпона на Windows, что часто позволяет использовать Linux-подобных подходов в окне Windows.
Ответ 2
Это о I/O, который по умолчанию используется для буферизации с помощью Python. Передайте -u
опции интерпретатору, чтобы отключить это поведение:
python -u producer.py | python consumer.py
Он исправляет проблему для меня.