简体   繁体   English

池回调中的异常处理

[英]Exception handling in Pool callback

Given this example scenario:鉴于此示例场景:

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 was hoping to see each value of i printed except for i=2 , which would instead have yielded an exception.我希望看到除i=2之外的i打印的每个值,否则会产生异常。

Instead I see something like the following:相反,我看到如下内容:

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

... and then execution just hangs. ...然后执行就挂了。

I'm aware that Pool handles callbacks on a separate thread, but why would execution hang and how can I reliably guard against errors in a task's callback?我知道Pool在单独的线程上处理回调,但是为什么执行会挂起,我如何可靠地防止任务回调中的错误?

This is happening because the exception inside the callback method is basically killing the thread that handles the Pool , as it does not have an except block to handle this kind of situation.发生这种情况是因为回调方法中的异常基本上杀死了处理Pool的线程,因为它没有一个except来处理这种情况。 After the Thread is dead, it's unable to join the worker_pool , so your application hangs. Thread死后, 它无法join worker_pool ,因此您的应用程序挂起。

I believe that's a decision made by the Python maintainers, so the best way to handle this exception is to envelop your code inside a try/except block and handle it, instead of bubbling and letting the thread be killed.我相信这是 Python 维护者做出的决定,因此处理此异常的最佳方法是将您的代码包含在 try/except 块中并处理它,而不是冒泡并让线程被杀死。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM