multiprocessing如何当子进程捕捉到异常,主进程和所有子进程终止

大家好,最近在使用multiprocessing处理问题,大致代码如下:

def work(i):
    #执行代码
    print('child success')
    pass
    
def throw_error(e):
    raise e
       
def main():
    pool = multiprocessing.Pool(processes=10)
    for i in range(0,5000):
        pool.apply_async(work, (i,), error_callback=throw_error)
    pool.close()
    pool.join()
    print('success')
    pass

这段代码在运行过程中,如果子进程有异常会被主进程捕捉到并抛出异常,整个过程也不会继续运行但也不会结束,需要在命令行ctl+c强制结束。我想问如果让当主进程捕捉到子进程异常,全部进程直接结束,代码部分应该怎么修改?

阅读 13.1k
2 个回答

原来的程序问题在于:子进程异常try Pool本身已经帮你做了,一旦回调到throw_error就说明异常发生了,这时候需要做的就是获取异常信息报警或者通知退出,你在这里raise e会导致主进程直接异常,Pool的调度是按照队列传参的,主进程异常整个队列就hold住了,程序就卡在那了。

至于说子进程异常时要退出除了进程组这种不优雅的方式,也可以kill调用实现优雅关闭,这都不是核心问题,父子进程的关闭问题可以参考https://blog.csdn.net/wenzhou...

自问自答,引用https://www.cnblogs.com/Tour/...:当在主进程中创建子进程时,主进程与其创建的子进程隶属于同一个分组里,这个分组的概念在linux中成为进程组,它是一个或多个进程的组成的集合,同一个进程组中的进程,它们的进程组ID是一致的。
在捕捉到exception的方法中增加:

def throw_error(e):
    print(e.__cause__)
    os.killpg(os.getpgid(os.getpid()), signal.SIGKILL)

这样既输出了错误,也把主进程和相关子进程都终止了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题