Как использовать KeyboardInterrupt из основного процесса, чтобы остановить дочерние процессы? - PullRequest
0 голосов
/ 21 мая 2018

Запуск приведенного ниже кода, а затем выполнение Ctrl+C может оставить p1, p2, p3 и p4 в фоновом режиме (где Ctrl+C ничего не делает).

Какиспользовать KeyboardInterrupt из основного процесса, чтобы он также останавливал все дочерние процессы?

import time
from multiprocessing import Process


def process(proc_n):
    while True:
        try:
            pass
        except KeyboardInterrupt:
            break
        except Exception as e:
            print(e)
        time.sleep(0.5)


def main():
    p1 = Process(target=process, args=(1,))
    p2 = Process(target=process, args=(2,))
    p3 = Process(target=process, args=(3,))
    p4 = Process(target=process, args=(4,))

    p1.start()
    p2.start()
    p3.start()
    p4.start()


if __name__ == '__main__':
    main()

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Если вы не хотите выполнять какой-либо код очистки для дочерних процессов, вы можете просто установить их как процесс-демон, и они завершатся, если завершится основной поток.

p1 = Process(target=process, args=(1,), daemon=True)

Если вы хотите провести некоторую очистку, вы можете использовать встроенный модуль atexit, чтобы зарегистрировать обработчик для выхода.

import atexit

def clean_up():
    # do some clean up
    ....

atexit.register(clean_up)

Так что функция clean_up будетвызываться при выходе из основного потока.

0 голосов
/ 21 мая 2018

Это зависит от вашего варианта использования.Если все, что вы хотите сделать, это завершить процессы, вы можете использовать метод Process.terminate(), чтобы остановить их.Вы также можете передать объект multiprocessing.Event процессам при их создании, а затем сделать так, чтобы основной процесс перехватил KeyboardInterrupt, а затем установить объект события.Вам нужно будет проверить событие в дочернем процессе, чтобы узнать, пора ли завершить работу.Если вы делаете более сложные сообщения, вы можете вместо этого использовать multiprocessing.Queue.Черт возьми, вы даже можете использовать сокеты для отправки сообщений между вашими процессами.Вот пример использования multiprocessing.Event:

from multiprocessing import Process, Event
from time import sleep


def proc(n, event):
    while not event.wait(1.0):
        pass


def main():
    event = Event()
    procs = []
    for i in range(4):
        procs.append(Process(target=proc, args=(i, event)))
        procs[-1].start()

    while True:
        try:
            sleep(1)
        except KeyboardInterrupt:
            event.set()
            break

    for p in procs:
        p.join()
...