Я пытаюсь перезапустить подпроцесс, если он падает, но почему-то этот цикл просто не работает. Мне было интересно, возможно ли это вообще?
def dont_stop(conv):
try:
subprocess.call(['python', 'main.py', str(conv)])
except:
dont_stop(conv)
if __name__ == '__main__':
proc = []
for conv in range(3,8):
p = multiprocessing.Process(name=f'p{conv}', target=dont_stop, args=(conv,))
p.start()
proc.append(p)
for p in proc:
p.join()
Функция subprocess.call
не вызывает исключение, если работающая программа завершается нестандартным образом. Все, что он делает, это возвращает «код возврата» из процесса, который вы сказали ему запустить. Обычно это 0
для процесса, который завершается нормально, и какое-то другое значение для программы, которая дает сбой (конкретные значения ненулевых значений различаются между программами и ОС).
Вот простое решение, которое заменяет ваш рекурсивный код циклом, который проверяет возвращаемое значение подпроцесса:
def dont_stop(conv):
retval = 1
while retval != 0: # a return value of zero indicates a normal exit
retval = subprocess.call(['python', 'main.py', str(conv)])
Альтернативный подход — перестать использовать subprocess.call
и вместо этого использовать subprocess.check_call
. Эта функция проверяет код возврата и возбуждает исключение, если он не равен нулю. Хотя часто это то, что мы предпочитаем, на самом деле это немного уродливее.
def dont_stop(conv):
while True:
try:
subprocess.check_call(['python', 'main.py', str(conv)])
break
except subprocess.CalledProcessError:
# do logging here?
pass
Поскольку программа, которую вы запускаете, также является программой Python, вы можете рассмотреть ее импорт, а не запускать в отдельном интерпретаторе. Это может позволить вашей функции dont_stop
напрямую взаимодействовать с кодом main.py
, например, перехватывать и регистрировать исключения. Детали этого слишком сильно зависят от дизайна main.py
и того, что он должен делать, поэтому я не собираюсь показывать предлагаемый код для этого подхода.
Я бы использовал
Queue
и отправил информацию об успехе или неудаче в основной цикл. Затем основной цикл перезапустит процесс.