Python concurrent.futures模块详解(线程池与进程池)
请解释concurrent.futures模块中ThreadPoolExecutor和ProcessPoolExecutor的用法、异同和最佳场景。submit()、map()和as_completed()的用法是什么?如何设置最大工作线程/进程数?Future对象的常用方法(result()/done()/cancel()/add_done_callback())如何使用?
回答
我是大山
统一接口:both继承Executor,提供submit、map、shutdown。
ThreadPoolExecutor vs ProcessPoolExecutor: | | ThreadPoolExecutor | ProcessPoolExecutor | |---|---|---| | 场景 | I/O密集型 | CPU密集型 | | GIL | 受GIL限制 | 无GIL(独立进程) | | 内存 | 共享 | 独立(需序列化) | | 参数传递 | 引用传递 | pickle序列化 |
核心API:
from concurrent.futures import ThreadPoolExecutor, as_completed
with ThreadPoolExecutor(max_workers=4) as executor:
# submit单个任务
future = executor.submit(fn, arg)
# map批量提交(保持顺序)
results = executor.map(fn, range(10))
# as_completed(按完成顺序处理)
futures = [executor.submit(fn, i) for i in range(10)]
for future in as_completed(futures):
print(future.result())
Future方法:
result(timeout=None):阻塞直到获得结果done():是否完成cancel():取消(未开始的任务可取消)add_done_callback(fn):完成后自动回调exception(timeout=None):获取异常
注意:ProcessPoolExecutor的__main__保护、submit的pickle限制、max_workers默认值(CPU核数×5 for线程池,CPU核数 for进程池)。