Pool 回调中的异常处理

Exception handling in Pool callback

鉴于此示例场景:

def _callback(result):
    if result == 2:
        # introduce an exception into one of the callbacks
        raise Exception("foo")

    print (result)

def _target(v):
    return v

worker_pool = Pool()

for i in range(10):
    worker_pool.apply_async(_target, args=(i,), callback=_callback)

worker_pool.close()
worker_pool.join()

我希望看到打印 i 的每个值,但 i=2 除外,否则会产生异常。

相反,我看到了如下内容:

0
1
Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 479, in _handle_results
    cache[job]._set(i, obj)
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 649, in _set
    self._callback(self._value)
  File "test3.py", line 6, in _callback
    raise Exception("foo")
Exception: foo

...然后执行挂起。

我知道 Pool 在单独的线程上处理回调,但为什么执行会挂起,我如何才能可靠地防止任务回调中的错误?

发生这种情况是因为回调方法中的异常基本上杀死了处理 Pool 的线程,如 it does not have an except block to handle this kind of situation. After the Thread is dead, it's unable to join the worker_pool,因此您的应用程序挂起。

我相信这是 Python 维护者做出的决定,因此处理此异常的最佳方法是将您的代码封装在 try/except 块中并处理它,而不是冒泡并让线程被杀死。