Как только subprocess.call
возвращается, подпроцесс выполняется - и возвращаемое значение call
является подпроцессом returncode
. Таким образом, накапливая эти коды возврата в списке pids
(что, между прочим, не синхронизируется между многопроцессорным добавлением и «основным» процессом) и отправляя им 9
сигналы «как если бы» они были идентификаторами процессов вместо возврата коды, безусловно, неправильно.
Еще одна вещь с вопросом, который определенно не так, это спецификация:
сможет убить их с помощью 'kill -9
parent_process_pid.
, поскольку -9
означает, что родительский процесс не может перехватить сигнал (это цель явного указания -9
) - поэтому я думаю, что -9
здесь ложно.
Вы должны использовать threading
вместо multiprocessing
(каждый поток или процесс "няни", по сути, ничего не делает, кроме как ожидает своего подпроцесса, так зачем тратить впустую процессы на такую легкую задачу? -); Вы также должны вызвать suprocess.Process
в главном потоке (чтобы запустить подпроцесс и получить его .pid
для включения в список) и передать полученный объект процесса потоку няни, который его ждет (и когда это сделано отчеты и удаляет его из списка). Список идентификаторов подпроцесса должен быть защищен блокировкой, так как основной поток и несколько потоков няни могут получить к нему доступ, и набор, вероятно, будет лучшим выбором, чем список (более быстрое удаление), так как вы не заботитесь ни о порядке, ни о порядке о том, как избежать дубликатов.
Итак, примерно (без тестирования, поэтому могут быть ошибки ;-) Я бы изменил ваш код на s / вещь вроде:
import subprocess, threading, signal
import sys, time
pobs = set()
pobslock = threading.Lock()
def numpobs():
with pobslock:
return len(pobs)
def sigterm_handler(signal, frame):
print 'You killed me!'
with pobslock:
for p in pobs: p.kill()
sys.exit(0)
def sigint_handler(signal, frame):
print 'You pressed Ctrl+C!'
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
signal.signal(signal.SIGTERM, sigterm_handler)
def f_wrapper(d, p):
print d, 'start', p.pid
rc = p.wait()
with pobslock:
pobs.remove(p)
print d, 'done, rc =', rc
print "Starting to run things."
for i in range(5):
p = subprocess.Popen(['sleep', '100'])
with pobslock:
pobs.add(p)
t = threading.Thread(target=f_wrapper, args=(i, p))
t.daemon=True
t.start()
print "Got things running ..."
while numpobs():
print "Still working ..."
time.sleep(1)