Как правильно работать с сигналами дочернего подпроцесса в родительском процессе? - PullRequest
0 голосов
/ 11 февраля 2019

Мне нужна помощь в следующем вопросе, у меня есть родительский процесс, который создает несколько бесконечных дочерних popen-подпроцессов, это могут быть ситуации, когда дочерний процесс не может работать из-за отсутствия некоторых установочных файлов.В таких ситуациях дочерний подпроцесс проблемы закрывается с помощью sys.exit внутри его кода.Я передаю информацию о том, что дочерний подпроцесс дробится в родительский процесс, выполняя sys.stderr.write в проблемном дочернем процессе, и прошу пользователя вручную перезапустить дробный дочерний подпроцесс (после настройки), но я хотел бы перехватить сигнал из sys.exit.в родительском процессе и удалите подпроцесс из словаря активных дочерних подпроцессов (словарь находится в главном процессе) при поступлении сигнала sys.exit.У меня есть предположение, что subprocessinstance.poll будет работать в этом случае, но я еще не пробовал, и я не уверен, работает ли он в моем случае.

Как запустить подпроцесс и добавить его в словарьв родительском процессе:

def add_ip_to_monitoring(ip: str, ip_in_monitoring_dict: dict) -> None:
if is_ip_address(ip):
    if not is_ip_already_in_monitoring(ip, ip_in_monitoring_dict):
        if sys.platform == 'win32':
            ip_in_monitoring_dict[ip] = subprocess.Popen(["python", "pingsubprocess.py", ip],
                                                         stdout=subprocess.DEVNULL)
        elif sys.platform == 'linux':
            ip_in_monitoring_dict[ip] = subprocess.Popen(["python3", "pingsubprocess.py", ip],
                                                         stdout=subprocess.DEVNULL)
        else:
            print(f"The program is not designed to work in your OS {sys.platform}")
            print("The program will be terminated in 5 seconds, Sorry...")
            time.sleep(5)
            print("Bye")
            time.sleep(1)
            sys.exit()

        print(f"{ip} was added to monitoring\n")
        iplist_file_op.write_ip_to_file(ip)

Как остановить дочерний подпроцесс:

def upload_smtp_settings():
settings = []
try:
    with open(file="settings.py", mode="r") as f:
        for i in f:
            settings.append(i.strip("\\\n"))
except FileNotFoundError:
    sys.stderr.write("Settings file does not exist or corrupted.\n\n")
    sys.stderr.write("Delete the file if it exists and do setup command\n\n")
    sys.stderr.write(f"{ip} session crushed.")
    sys.stderr.write("To restore session to the ip, remove it from monitoring, then add it again!")
    sys.stderr.flush()
    sys.exit()
return settings

Ссылка на мой проект для получения более подробной информации, проект работает, но мне нужно дать ему больше функций:https://github.com/ArtyomKozyrev1989/ICMP_Ping_Monitor_True_CLI?fbclid=IwAR2ksD70q8SksXuw9p3SEHhkk5-N46fy0lCt5jGGbLaIJaKs-dGFbBWQsfc

1 Ответ

0 голосов
/ 11 февраля 2019

Мое решение ниже, если кто-нибудь может дать какие-либо рекомендации, пожалуйста, мне также интересно, как я могу отправить информацию от мастера ребенку, когда ребенок уже активен:

def check_if_all_subprocess_alive(popen_list: dict)-> dict:
if popen_list:
    popen_list_copy = popen_list.copy()
    for ip in popen_list.keys():
        if popen_list[ip].poll() is not None:
            cli_menu.remove_ip_from_monitoring(ip, popen_list_copy)
    popen_list = popen_list_copy
return popen_list

def main():
popen_list = {} # dictionary of popen subprocesses
cli_menu.hello_banner()
while True:
    command = input("CLI>: ")
    command = cli_menu.analyze_command(command)
    if command[0] in menu_wrapper.keys():
        menu_wrapper[command[0]](popen_list, command)
    elif command[0] == "FreeSpace":
        print()
    else:
        print("Incorrect command, Please try again.\n")
    popen_list = check_if_all_subprocess_alive(popen_list)
...