如何从主进程使用KeyboardInterrupt来停止子进程?

时间:2018-05-21 01:43:06

标签: python python-3.x multiprocessing signals python-multiprocessing

运行以下代码然后执行Ctrl+C可以让p1p2p3p4在后​​台运行(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 :(得分:0)

这取决于您的用例。如果您要做的就是终止进程,可以使用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()

答案 1 :(得分:0)

如果您不想为子进程执行一些清理代码,您可以简单地将它们设置为守护程序进程,如果主线程终止,它们将终止。

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

如果要进行一些清理,可以使用atexit内置模块注册退出处理程序。

import atexit

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

atexit.register(clean_up)

因此,当主线程退出时,将调用函数clean_up