← [ BACK_TO_NOTES ]

Python 多进程与进程池

多进程绕过 GIL 做 CPU 并行;注意序列化、内存与启动方式,优先进程池管理生命周期。

#concept #growing #dev #python #python

[!info] related notes

Python 多进程与进程池

这个概念为什么出现

在启用 GIL 的 CPython 中,纯 Python CPU 循环用线程通常难以多核并行。进程提供独立解释器,但需承担序列化、启动和内存成本;压缩、哈希、图像库可能在原生层释放 GIL,不能只按任务名称判断。

[!abstract] 一句话理解 进程池把 CPU 任务分到多进程执行以绕过 GIL;参数/返回值需可 pickle,适合可分割的计算型负载。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:将四组纯 Python 累加任务交给进程池

# process_pool_hash.py
# 示例意图:分发纯 Python 累加任务;不计算文件哈希或校验和。
# 教学点:
# - ProcessPoolExecutor;
# - 顶层可 pickle 函数;
# - if __name__ 保护(spawn/forkserver)。

from concurrent.futures import ProcessPoolExecutor
from time import perf_counter


def crunch(n: int) -> int:
    # 模拟 CPU:累加
    total = 0
    for i in range(n):
        total += i % 7
    return total


def main() -> None:
    work = [300000] * 4
    t0 = perf_counter()
    with ProcessPoolExecutor(max_workers=4) as pool:
        results = list(pool.map(crunch, work))
    print("results:", results)
    print("elapsed≈", round(perf_counter() - t0, 3))


if __name__ == "__main__":
    main()

建议运行:

python process_pool_hash.py

期望输出(elapsed 随机器变化):

results: [899997, 899997, 899997, 899997]
elapsed≈ 0.xxx

结合场景再看三个关注点

  1. 函数与参数/结果需可 pickle,工作函数通常应定义在可导入模块顶层;REPL/Notebook 中的 __main__ 不一定可被子进程导入。
  2. if __name__ == "__main__" 防止 spawn 递归。
  3. 任务太小会被进程开销吃掉收益。

核心概念与准确模型

  • multiprocessing / ProcessPoolExecutor
  • 启动方式与平台/版本有关:Windows/macOS 通常用 spawn;3.14 在支持 forkserver 的 POSIX 平台默认改为 forkserver,fork 不再是任何平台的默认方式。需要特定语义时显式传 mp_context。
  • 队列、共享内存进阶 API
  • 与线程池接口相似(futures)

边界情况与反直觉行为

  1. lambda/闭包难 pickle。
  2. 大对象传输成为瓶颈。
  3. 全局可变状态不因子进程启动就实时共享;fork 的初始内存快照也不是共享更新,需显式 IPC/共享内存。
  4. Future.result(timeout=…) 只限制等待,不停止运行中的进程任务;cancel 通常只能取消尚未开始的任务,退出池上下文默认仍等待任务结束。

常见误区

[!warning] 常见误区:所有变慢都上多进程 错误理解:进程越多越快。
正确模型:先确认 CPU 瓶颈与任务粒度。

工程实践

  • 池大小≈CPU 核数(容器限额内)
  • 批处理合并小任务
  • 失败重试与超时

本节总结

多进程是 CPython CPU 并行主路径之一;把它当分布式计算的缩小版管理。

自测题

  1. 为什么需要 if __name__ 保护?
  2. 为何小任务可能不加速?
参考答案
  1. spawn 会再导入主模块,无保护会重复启动。
  2. 进程启动与序列化开销大于计算本身。

延伸阅读与资料来源

资料类型支撑内容
multiprocessing文档进程
ProcessPoolExecutor文档进程池
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本