Как я могу узнать, почему subprocess.Popen wait () ждет вечно, если stdout = PIPE? - PullRequest
20 голосов
/ 18 сентября 2009

У меня есть программа, которая пишет в stdout и, возможно, в stderr. Я хочу запустить его из python, захватив stdout и stderr. Мой код выглядит так:

from subprocess import *

p = Popen( exe, shell=TRUE, stdout=PIPE, stderr=PIPE )
rtrncode = p.wait()

Для пары программ это работает нормально, но когда я добавил новую, новая зависает навсегда. Если я удаляю stdout=PIPE, программа записывает свой вывод в консоль и завершает работу, и все в порядке. Как я могу определить причину зависания?

Использование python 2.5 в Windows XP. Программа не читает со стандартного ввода и не имеет какого-либо пользовательского ввода (то есть «нажать клавишу»).

Ответы [ 2 ]

42 голосов
/ 18 сентября 2009

Когда буфер канала заполняется (обычно 4 КБ или около того), процесс записи останавливается, пока процесс чтения не прочитает некоторые из рассматриваемых данных; но здесь вы ничего не читаете, пока не завершится подпроцесс, отсюда тупик. В документах на wait очень четко сказано:

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

Если по какой-то причине вы не можете использовать communicate, пусть подпроцесс записывает во временный файл, а затем вы можете wait и прочитать этот файл, когда он будет готов - запись в файл, а не в труба, не рискует тупик.

3 голосов
/ 18 сентября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...