Избегайте подпроцесса. Откройте stdout трубы засорения и замораживания дочернего процесса - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть случай использования, когда мне нужно запустить процесс (веб-сервер IIS Express), подождать, пока он напечатает определенную строку, чтобы убедиться, что он полностью инициализирован, а затем прекратить чтение его вывода и запустить другую операцию блокировки:

proc = subprocess.Popen('iisexpress.exe /path:<bla bla bla>', shell=True, stdout=subprocess.PIPE);
# .... <read some output>
os.system('nunit <bla bla bla>') # This takes a long time

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

Я думаю о 2 подходах - либо запустить новый поток в моем скрипте Python, чтобы прочитать и удалить строки из дочернего процесса, либонайти способ перенаправить канал на /dev/null после того, как я закончу читать с него.

Какой из подходов мне выбрать?

1 Ответ

0 голосов
/ 12 сентября 2018

Вам нужно будет прочитать все материалы с первого процесса. Вы можете сделать это, разветвившись и прочитав (и забыв) все в дочернем процессе, или разделив отдельный поток, чтобы сделать это. Я бы предпочел нить подход:

import threading

proc = subprocess.Popen('iisexpress.exe /path:<bla bla bla>',
                        shell=True, stdout=subprocess.PIPE)

# now wait for the trigger line:
while trigger not in proc.stdout.readline():
    pass

# start a thread for reading the rest:
def read_and_drop():
    while proc.stdout.readline():
        pass

threading.Thread(target=read_and_drop)

# here start the other process:
os.system('nunit <bla bla bla>')

Я предполагаю, что первый процесс напечатает свой вывод построчно. Если вместо этого он печатает 4 ТБ текста без перевода строки, это не будет работать должным образом (поскольку поток пытается прочитать полные строки). Пожалуйста, прокомментируйте, если это проблема для вас, тогда я могу дать немного менее читаемую и немного более длинную версию, которая также занимается этим.

...