Как правильно взаимодействовать с процессом с помощью модуля подпроцесса

У меня проблемы с перенаправлением 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

Флаг -u решит эту проблему для подпроцесса Python. Также существуют модули pexpect, pty и утилиты unbuffer, stdbuf, script, которые могут помочь исправить проблему с буферизацией блоков.

jfs 22.05.2013 23:33
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
11
2
14 751
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не соответствует вашему примеру на 100%, но помогает понять основную проблему: процесс P запускает дочерний элемент C. Ребенок C записывает что-то в свой стандартный вывод. stdout C - это канал с буфером на 4096 символов, и вывод короче этого значения. Теперь C ждет ввода. Для C все нормально.

P ожидает вывода, который никогда не придет, потому что ОС не видит причин очищать выходной буфер C (с таким небольшим количеством данных в нем). Поскольку P никогда не получает вывод C, он никогда ничего не записывает в C, поэтому C зависает, ожидая ввода от P.

Исправление: используйте сброс после каждой записи в канал, заставляя ОС отправлять данные сейчас.

В вашем случае добавление proc.stdin.flush() в основной цикл while и sys.stdout.flush() в дочерний цикл после печати должно решить вашу проблему.

Вам также следует подумать о перемещении кода, который читает из другого процесса, в поток. Идея здесь в том, что вы никогда не узнаете, когда будут получены данные, и использование потока помогает вам понять эти проблемы, пока вы пишете код, обрабатывающий результаты.

Здесь я хотел показать вам новую документацию по Python 2.6, но она также не объясняет проблему с промывкой :( Ну что ж ...

Хорошее объяснение. Еще из документации pexpect: В: Почему бы просто не использовать канал (popen ())?

jfs 22.05.2013 23:27

Документы Pexpect перемещены: вот новая ссылка

jfs 13.09.2016 18:12

Другие вопросы по теме