如何处理多进程.Pool中的初始化器错误?

2022-04-10 00:00:00 python python-multiprocessing

问题描述

当初始值设定项抛出如下错误时,脚本不会停止。
我想在启动主进程之前中止(不要运行‘do_omething’)。

from multiprocessing import Pool
import contextlib

def initializer():
    raise Exception("init failed")

def do_something(args):
    # main process
    pass

pool = Pool(1, initializer=initializer)
with contextlib.closing(pool):
    try:
        pool.map_async(do_something, [1]).get(100)
    except:
        pool.terminate()

控制台上的永不停止堆栈跟踪如下

...
Exception: init failed
Process ForkPoolWorker-18:
Traceback (most recent call last):
  File "/home/hoge/anaconda3/lib/python3.6/multiprocessing/process.py", line 249, in _bootstrap
    self.run()
  File "/home/hoge/anaconda3/lib/python3.6/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/home/hoge/anaconda3/lib/python3.6/multiprocessing/pool.py", line 103, in worker
    initializer(*initargs)
  File "hoge.py", line 5, in initializer
    raise Exception("init failed")
Exception: init failed
...

我的解决方法是通过使用如下所示的全局标志在主进程开始时抑制初始值设定项错误和返回。
但我想学更好的。

def initializer():
    try:
        raise Exception("init failed")
    except:
        global failed
        failed = True

def do_something(args):
    global failed
    if failed:
        # skip when initializer failed
        return
    # main process

在使用推荐答案浏览了多处理的实现后,我确信没有更好的解决方案,因为如果存在任何工作进程--无论是意外的还是初始化失败的,池都会启动一个线程,通过_repanate_pool()来_Maintain_Pool()。

查看:Lib/multiprocessing/pool.py line 244

相关文章