代码之家  ›  专栏  ›  技术社区  ›  Greg

如何使用来自主进程的键盘中断来停止子进程?

  •  1
  • Greg  · 技术社区  · 8 年前

    运行以下代码,然后执行 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 回复  |  直到 8 年前
        1
  •  0
  •   Sraw    8 年前

    如果不想为子进程执行一些清理代码,只需将它们设置为守护进程,如果主线程终止,它们将终止。

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

    如果你想清理一下,你可以用 atexit 用于注册退出处理程序的内置模块。

    import atexit
    
    def clean_up():
        # do some clean up
        ....
    
    atexit.register(clean_up)
    

    So函数 clean_up 将在主线程退出时调用。

        2
  •  0
  •   Broseph    8 年前

    这取决于您的用例是什么。如果您只想终止进程,那么可以使用 Process.terminate() 阻止他们的方法。你也可以通过 multiprocessing.Event 当您创建进程时,将对象指向这些进程,然后让主进程捕获 KeyboardInterrupt 然后设置事件对象。您需要检查子进程中的事件,以确定是否是关闭的时候。如果要执行更复杂的消息传递,则可能需要使用 multiprocessing.Queue 相反。甚至可以使用套接字在进程之间发送消息。下面是一个使用 多处理.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()