【问题标题】:How to use KeyboardInterrupt from the main process to stop child processes?如何使用主进程中的 KeyboardInterrupt 来停止子进程?
【发布时间】:2018-10-30 15:30:42
【问题描述】:

运行以下代码然后执行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()

【问题讨论】:

  • 如果您不想为子进程执行一些清理代码,您可以简单地将它们设置为守护进程,如果主线程终止,它们将终止。 p1 = Process(target=process, args=(1,), daemon=True)
  • @Sraw 如果您将您的评论作为答案发表,我会接受 - 这正是我想要的。

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


【解决方案1】:

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

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

如果你想做一些清理工作,你可以使用atexit内置模块注册一个处理程序以退出。

import atexit

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

atexit.register(clean_up)

所以函数clean_up会在主线程退出时被调用。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2017-01-22
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多