文章目录
背景方案设计ThreadPool类使用方法简单设计一个会抛出异常的函数最终方案
背景
随着数据量增多,业务中处理该类数据的模块需要从串行处理升级成多线程处理。原流程中只有部分流程需要多线程优化,而多线程的执行结果又为上层所需。需要并行化的流程中可能出现异常。选择的线程池为multiprocessing.pool.ThreadPool。python解释器:官方cpython,2.7.15
方案设计
ThreadPool类使用方法
from multiprocessing.pool import ThreadPool
# 创建一个线程池
pool_size = 4
thread_pool = ThreadPool(pool_size)
# 调用map方法,将会对迭代对象拆包并各自开启线程交由目标函数处理
pool_output = thread_pool.map(目标的函数,可迭代对象)
# 关闭线程,禁止新线程加入;随后主线程等待其结束
thread_pool.close()
thread_pool.join()
官方文档只说明了map方法可以返回各个目标函数的结果,但却没有交待当线程抛出异常时会如何处理
简单设计一个会抛出异常的函数
def square_may_fail(num):
"""
本函数会计算并返回入参的平方,
但当入参为10的倍数时抛出异常
"""
print(num)
if num % 10 ==0:
raise Exception('find 10 mutiple')
else:
return num ** 2
# 在这里所有线程都会运行(包括抛出异常的),但pool_output不存在
pool_output = thread_pool.map(square_may_fail, range(11))
print(pool_size)
这种方案下无法得到任何有效返回值,且还需要在map的外层用try…except包住。如果对返回结果不敢兴趣,且不在乎中间运行的细节,可以采用这种方案。
最终方案
上述方案无法满足掌控线程运行状态的需求。且线程运行时出现的异常尽可能在线程内捕获处理,因此采取以下方案
def square_may_fail(num):
"""
本函数会计算并返回入参的平方,
但当入参为10的倍数时抛出异常
"""
print(num)
try:
if num % 10 ==0:
raise Exception('find 10 mutiple')
else:
return num ** 2
except Exception as e:
return e
这时候map方法能够正常返回所有线程的执行结果,在上层中根据结果作下一步处理。