cpu密集型任务必须用multiprocessing.pool或processpoolexecutor,因gil使threading无效;注意函数需顶层定义、参数可序列化、避免大对象传递;windows下必须加if name == '__main__':保护。

用 multiprocessing.Pool 做 CPU 密集型任务,别用 threading
Python 的 GIL 让 threading 在 CPU 密集型任务里几乎不加速,反而因线程切换拖慢速度。真正要并行算数、图像处理、数值计算,必须走 multiprocessing。
常见错误是把耗时函数写成闭包或带非序列化对象(比如文件句柄、数据库连接、lambda),导致 Pool.map() 报 PicklingError。
-
Pool启动的子进程无法访问主进程的全局变量或局部作用域,函数必须定义在模块顶层 - 传参只能是可序列化的类型:
int、str、list、dict、numpy.ndarray(需注意共享内存配置) - 避免在
map()里传大对象——每次都会 pickle/unpickle,比计算还慢;改用multiprocessing.Manager()或共享内存(如Array/Value)
concurrent.futures.ProcessPoolExecutor 比 Pool 更适合写脚本
如果你不是在写长期运行的服务,而是写一个跑完就退出的脚本(比如批量处理 CSV、调用模型推理),ProcessPoolExecutor 的上下文管理更安全、API 更直觉,且能统一处理异常。
它和 multiprocessing.Pool 底层用的是一套机制,但默认行为更“防呆”:比如子进程崩溃时不会静默失败,而是抛出 BrokenProcessPool;任务超时也能直接设 timeout 参数。
- 用
as_completed()获取结果顺序不依赖输入顺序,适合“谁先算完谁先返回”场景 -
submit()返回Future对象,可以调用.result(timeout=5)主动等结果,超时就报错,比Pool.apply_async().get()更可控 - 别在
with ProcessPoolExecutor() as executor:外面保留Future引用——进程池关闭后,Future.result()会卡死或报CancelledError
Windows 下启动 multiprocessing 必须加 if __name__ == '__main__':
这是 Windows(以及部分旧版 macOS)上最常踩的坑:不加保护,子进程会重复导入主模块,触发递归创建新进程,最终爆内存或报 RuntimeError: An attempt has been made to start a new process before the current process has finished its bootstrapping phase.
不是风格问题,是平台限制——Windows 用的是 spawn 方式启动子进程,而非 Unix 的 fork。
- 所有
multiprocessing或concurrent.futures的创建代码(Pool()、ProcessPoolExecutor()、Process())必须包在if __name__ == '__main__':里 - 即使你只在 Jupyter 里测试,也得用
if True:临时绕过(但正式脚本必须写对) - PyInstaller 打包后仍需此保护,否则生成的 exe 运行时报错
IO 密集型任务优先选 concurrent.futures.ThreadPoolExecutor
爬网页、读写文件、调 API —— 这类任务大部分时间在等响应,GIL 不构成瓶颈。ThreadPoolExecutor 启动快、内存开销小、共享变量方便,比开一堆进程划算得多。
但要注意:线程间共享数据不加锁会出错,尤其是对同一变量做 += 或修改列表/字典。
- 用
threading.Lock()保护临界区,或者干脆用线程安全结构,比如queue.Queue - 别在线程里用
time.sleep()模拟等待——它会释放 GIL,但实际应交给异步 I/O(如aiohttp)更高效 - 如果混合 CPU + IO 任务(比如下载完立刻解压),别硬塞进同一个线程池;拆成
ThreadPoolExecutor负责下载 +ProcessPoolExecutor负责解压,再用Future链式调度
多任务并行不是选“看起来高级”的方案,而是看瓶颈在哪、数据怎么传、平台怎么启动——搞错一点,性能可能比单线程还差。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











