У меня возникают некоторые проблемы при использовании subprocess.Popen()
для порождения нескольких экземпляров одного и того же приложения из моего скрипта python, использующего потоки для их одновременной работы. В каждом потоке я запускаю приложение с помощью вызова popen()
, а затем жду его завершения, вызывая wait()
. Кажется, проблема в том, что wait()
-all фактически не ждет завершения процесса. Я экспериментировал, используя только один поток и распечатывая текстовые сообщения, когда процесс начинается и когда он заканчивается. Таким образом, функция потока будет выглядеть примерно так:
def worker():
while True:
job = q.get() # q is a global Queue of jobs
print('Starting process %d' % job['id'])
proc = subprocess.Popen(job['cmd'], shell=True)
proc.wait()
print('Finished process %d' % job['id'])
job.task_done()
Но даже если я использую только один поток, он напечатает несколько сообщений «Запуск процесса ...», прежде чем появится сообщение «Завершенный процесс ...». Есть ли случаи, когда wait()
на самом деле не ждет? У меня есть несколько различных внешних приложений (консольные приложения C ++), в которых, в свою очередь, будет запущено несколько экземпляров одновременно, и для некоторых из них мой код работает, а для других - нет. Может ли быть проблема с внешними приложениями, которая как-то влияет на вызов wait()
?
Код для создания потоков выглядит примерно так:
for i in range(1):
t = Thread(target=worker)
t.daemon = True
t.start()
q.join() # Wait for the queue to empty
Обновление 1 :
Я также должен добавить, что для некоторых внешних приложений я иногда получаю код возврата (proc.returncode
) -1073471801. Например, одно из внешних приложений выдаст этот код возврата первые два раза, когда вызывается Popen
, но не последние два (когда у меня четыре задания).
Обновление 2 :
Чтобы прояснить ситуацию, сейчас у меня в очереди четыре задания, то есть четыре разных тестовых случая. Когда я запускаю свой код, для одного из внешних приложений первые два Popen
-вызова генерируют код возврата -1073471801. Но если я распечатываю точную команду, которую Popen
вызывает, и запускаю ее в командном окне, она выполняется без проблем.
Решено!
Мне удалось решить проблемы, которые у меня были. Я думаю, что проблема была в моем отсутствии опыта в многопоточном программировании. Я упустил тот факт, что когда я создавал свои первые рабочие потоки, они продолжали жить до тех пор, пока не завершится сценарий python. По ошибке я создавал больше рабочих потоков каждый раз, когда помещал новые элементы в очередь (я делаю это партиями для каждой внешней программы, которую я хочу запустить). Так что к тому времени, когда я добрался до четвертого внешнего приложения, у меня было запущено четыре потока одновременно, хотя я только думал, что у меня есть один.