Python中ThreadPool的apply_async传错参数不抛异常的原因及解决
异常未输出的原因
multiprocessing.pool.ThreadPool的apply_async为异步任务提交接口,子线程执行任务过程中抛出的异常会被线程池内部默认捕获,暂存在返回的AsyncResult实例中,不会主动抛到主线程、也不会自动打印到控制台,你没有主动读取异常的话,就会出现程序无报错直接退出的情况。- 你的示例代码本身存在参数传递语法问题:Python 中单元素元组需要在元素后加逗号,
(d)会被识别为普通整数而非参数元组,相当于仅给需要2个入参的console_log传了1个参数,必然触发参数缺失异常,只是该异常被线程池吞掉了没有输出。
捕获线程池异常的可用方法
- 主动调用AsyncResult的get()方法
apply_async返回的AsyncResult实例的get()方法会阻塞等待任务执行完成,任务有异常时会直接抛到主线程:
for d in data: res = pool.apply_async(console_log, (d,)) res.get() # 任务出错时会在此处抛出异常
如果不需要同步阻塞,可以在所有任务提交完成后,统一遍历所有返回的AsyncResult实例调用get()。
- 使用error_callback参数捕获异常
Python 3.2及以上版本支持给apply_async传入error_callback参数,任务执行抛出异常时会自动触发该回调,传入异常对象作为参数,你可以在回调内自定义错误处理逻辑:
def callback_error(e): print('任务执行出错:', e) # 可打印完整堆栈信息方便调试 import traceback traceback.print_exc() for d in data: pool.apply_async(console_log, (d,), error_callback=callback_error)
- 在任务函数内部增加异常捕获
直接在被线程池调用的函数内部套try-except,自行捕获处理所有异常:
def console_log(id, msg): try: print("{} : {}".format(id, msg)) except Exception as e: import traceback traceback.print_exc()
内容的提问来源于stack exchange,提问作者fist ace
相关产品推荐
相关产品推荐

