Как обрабатывать SIGTERM при получении из подпроцесса. Открыть на рабочих в многопроцессорной обработке. Процессы без завершения дерева процессов - PullRequest
0 голосов
/ 04 октября 2018

У меня есть скрипт на python, который создает многопроцессорные процессы, и каждый рабочий процесса использует subprocess.Popen для запуска некоторых операций базы данных с помощью утилиты базы данных linuxИногда утилита базы данных отправляет SIGTERM.Как мне обработать SIGTERM, поступающий из команды linux, без завершения всего дерева процессов, а также текущего рабочего процесса?

Пока мой код:

import multiprocessing as mp
import subprocess
import shlex
import signal

class SigTermError(Exception):
    pass

def sig_handler(sig, frame):
    raise SigTermError( ("Received Signal:{} "
                     "on line:{} in file:{}")
                    .format(str(sig)
                            , str(frame.f_lineno)
                            , frame.f_code.co_filename))

def do_something_to_hanlde_sigterm():
    print('Handled SIGTERM')

def move_on():
    print('Moving on')



def run_shell_command(cmd_string):
    """ Run a shell command"""
    original_sigterm_handler = signal.getsignal(signal.SIGTERM)
    signal.signal(signal.SIGTERM, sig_handler)
    args = shlex.split(cmd_string)

    # I want to handle the SIGTERM and if the cmd_string sends a SIGTERM then return a ret_code of -99
    try:
        p = subprocess.Popen(args, shell=False
                             , stdout=subprocess.PIPE
                             , stderr=subprocess.PIPE
                             )


        out, err = p.communicate() # This fails if the cmd_string sends a SIGTERM

        ret_code = p.returncode
    except SigTermError:
        ret_code = -99
    finally:
        signal.signal(signal.SIGTERM, original_sigterm_handler)
        return ret_code


def worker(arg1, arg2):
    """ Run db_command with 2 arguments. """
    cmd_string = 'db_command -parameter1 {arg1} -parameter2 {arg2}'.format(arg1=arg1,arg2=arg2)
    func_return = run_shell_command(cmd_string)  # The whole process tree terminates if subprocess sends sigterm
    if func_return == -99:
        do_something_to_hanlde_sigterm()
    else:
        move_on()

if __name__ == '__main__':

    processes = [mp.Process(target=worker, args=(x, x*x)) for x in list(range(4))]

    for p in processes:
        p.start()

    for p in processes:
        p.join()

    print('All Done')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...