Как правильно взаимодействовать с процессом с помощью модуля подпроцесса
У меня проблемы с перенаправлением stdio другой программы с помощью модуля подпроцесса. Просто чтение из stdout приводит к зависанию, и Popen.communicate() работает, но закрывает каналы после чтения / записи. Какой самый простой способ реализовать это?
Я играл с этим на окнах:
import subprocess
proc = subprocess.Popen('python -c "while True: print \'Hi %s!\' % raw_input()"',
shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
while True:
proc.stdin.write('world\n')
proc_read = proc.stdout.readline()
if proc_read:
print proc_read
1 ответ
Не соответствует 100% вашему примеру, но помогает понять основную проблему: процесс P запускает дочерний C. Дочерний C записывает что-то в свой стандартный вывод. stdout C - это канал, который имеет 4096-символьный буфер, и вывод у него короче. Теперь C ждет некоторого ввода. Для С все нормально.
P ожидает вывода, который никогда не будет получен, потому что ОС не видит причин для очистки буфера вывода C (так мало данных в нем). Поскольку P никогда не получает выходные данные C, он никогда ничего не записывает в C, поэтому C зависает в ожидании ввода от P.
Исправлено: используйте сброс после каждой записи в канал, заставляющий ОС отправлять данные сейчас.
В вашем случае добавление proc.stdin.flush()
в основном цикле и sys.stdout.flush()
в дочернем цикле после печати должна исправить вашу проблему.
Вам также следует рассмотреть возможность перемещения кода, который читает другой процесс, в поток. Идея в том, что вы никогда не узнаете, когда поступят данные, и использование потока поможет вам понять эти проблемы, пока вы пишете код, который обрабатывает результаты.
В этом месте я хотел показать вам новую документацию по Python 2.6, но она также не объясняет проблему сброса:(О, хорошо...