Как перезапустить подпроцесс, если он вылетает?

Я пытаюсь перезапустить подпроцесс, если он падает, но почему-то этот цикл просто не работает. Мне было интересно, возможно ли это вообще?

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()

Я бы использовал Queue и отправил информацию об успехе или неудаче в основной цикл. Затем основной цикл перезапустит процесс.

Nechoj 06.05.2022 22:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
24
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Функция 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 и того, что он должен делать, поэтому я не собираюсь показывать предлагаемый код для этого подхода.

Другие вопросы по теме

Java.lang.IllegalStateException Вызвано: android.database.sqlite.SQLiteCantOpenDatabaseException
Один поток и асинхронная путаница
Исполнителю пула потоков требуется предложение по функции вызова или несколько шагов перед вызовом executor.submit
Std элемент доступа к карте при создании новой безопасности одного потока
Ошибка Отсутствует указание типа. Предполагается . Примечание C++ не поддерживает инициализацию по умолчанию
Почему порождение процесса заставляет вычисления выполняться в два раза быстрее?
При этом синхронизация не работает. Почему? Я синхронизировал все методы. Может ли кто-нибудь рассказать и предоставить решение для того же?
Почему мои темы не работают так, как я ожидаю?
Я не понимаю эту пожизненную ошибку: создание потоков внутри функции структуры
Как заставить графический интерфейс Python Tkinter проверять, завершил ли другой поток внесение изменений в графический интерфейс?