Я использую многопроцессорную библиотеку для создания двух дочерних процессов. Я хотел бы убедиться, что до тех пор, пока родительский процесс жив, если дочерние процессы умирают (получают SIGKILL или SIGTERM), они автоматически перезапускаются. С другой стороны, если родительский процесс получает SIGTERM/SIGINT, я хочу, чтобы он завершил все дочерние процессы, а затем вышел из него.Многопроцессорность Python - Захват сигналов для перезапуска дочерних процессов или закрытия родительского процесса
Это, как я подошел к этой проблеме:
import sys
import time
from signal import signal, SIGINT, SIGTERM, SIGQUIT, SIGCHLD, SIG_IGN
from functools import partial
import multiprocessing
import setproctitle
class HelloWorld(multiprocessing.Process):
def __init__(self):
super(HelloWorld, self).__init__()
# ignore, let parent handle it
signal(SIGTERM, SIG_IGN)
def run(self):
setproctitle.setproctitle("helloProcess")
while True:
print "Hello World"
time.sleep(1)
class Counter(multiprocessing.Process):
def __init__(self):
super(Counter, self).__init__()
self.counter = 1
# ignore, let parent handle it
signal(SIGTERM, SIG_IGN)
def run(self):
setproctitle.setproctitle("counterProcess")
while True:
print self.counter
time.sleep(1)
self.counter += 1
def signal_handler(helloProcess, counterProcess, signum, frame):
print multiprocessing.active_children()
print "helloProcess: ", helloProcess
print "counterProcess: ", counterProcess
if signum == 17:
print "helloProcess: ", helloProcess.is_alive()
if not helloProcess.is_alive():
print "Restarting helloProcess"
helloProcess = HelloWorld()
helloProcess.start()
print "counterProcess: ", counterProcess.is_alive()
if not counterProcess.is_alive():
print "Restarting counterProcess"
counterProcess = Counter()
counterProcess.start()
else:
if helloProcess.is_alive():
print "Stopping helloProcess"
helloProcess.terminate()
if counterProcess.is_alive():
print "Stopping counterProcess"
counterProcess.terminate()
sys.exit(0)
if __name__ == '__main__':
helloProcess = HelloWorld()
helloProcess.start()
counterProcess = Counter()
counterProcess.start()
for signame in [SIGINT, SIGTERM, SIGQUIT, SIGCHLD]:
signal(signame, partial(signal_handler, helloProcess, counterProcess))
multiprocessing.active_children()
Если я отправить SIGKILL на встречную, он будет правильно перезагрузиться. Однако отправка SIGKILL в helloProcess также перезапускает counterProcess вместо helloProcess?
Если я отправлю SIGTERM родительскому процессу, родительский выход будет завершен, но дочерние процессы станут сиротами и продолжат работу. Как исправить это поведение?
'обработчика signal.SIGCHLD' и' multiprocessing.Process' не работает вместе. В обработчике 'signal.SIGCHLD'' Process.is_alive' возвращает 'True' даже после того, как дочерний элемент завершился. –