应优先使用 pool 而非手动管理 process:pool 自动处理进程生命周期、任务分发、结果收集与异常传播,避免僵尸进程;需遵守 windows 的 if name == "__main__": 规则;calcul 函数须定义在模块顶层且可被 pickle;进程数不宜盲目设为 cpu_count(),应实测调优;务必加超时机制防卡死。

能直接用 Pool 就别手写 Process,尤其当你在做参数搜索、批量计算或数据预处理这类“一堆独立任务等结果”的场景时。
为什么必须用 Pool 而不是裸写 Process
手动管理 Process 对象容易漏掉 join() 或提前退出,导致子进程变成僵尸进程;更关键的是,任务分发、结果收集、异常传播全得自己兜底。而 Pool 内置了这些逻辑,且默认复用进程(避免反复 fork 开销)。
-
Pool.map()自动把输入列表切片、分发到各进程、阻塞等待全部完成并按原顺序返回结果 -
Pool.apply_async()适合任务间无依赖、你愿意自己用.get()拿结果的场景 - Windows 下不加
if __name__ == "__main__":会直接报错——这是 spawn 启动方式的硬性要求,不是可选项
calcul 函数必须能被子进程 import 到
子进程启动时会重新导入主模块,如果 calcul 定义在 if __name__ == "__main__": 块里,或者依赖未导出的局部变量,就会抛 NameError 或 AttributeError。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 把
calcul放在模块顶层(即和import语句同级),确保它可被任意子进程 import - 避免在
calcul里用闭包变量、lambda 或嵌套函数——它们无法被 pickle 序列化传给子进程 - 如果函数依赖外部状态(如全局配置字典),改用
initializer+initargs注入,而不是靠模块级变量
别盲目设 processes=mp.cpu_count()
物理核心数 ≠ 最优并发数。比如 Apple M2 芯片有 8 核(4 性能核 + 4 能效核),但跑纯 CPU 计算时,4 个性能核已接近饱和;设成 8 反而因调度开销和内存带宽争抢拖慢整体速度。
- 先试
processes=4,再逐步加到 6、8,用time.perf_counter()实测耗时变化 - 若
calcul含 I/O(如读文件、调 API),适当增加进程数可能有益,但要警惕系统句柄耗尽 - Linux/macOS 上可用
psutil.cpu_count(logical=False)获取物理核心数作参考起点
真正卡住的往往不是怎么写并行,而是子进程崩溃后主进程静默卡死——记得给 pool.map() 加超时(用 pool.map_async(...).get(timeout=60)),并捕获 multiprocessing.TimeoutError 和 Exception。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










