为什么 Python 多线程越跑越慢?彻底搞懂 GIL!

0 阅读2分钟

本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

Python 的 GIL(Global Interpreter Lock,全局解释器锁) 是 CPython 解释器中的一把互斥锁,用于保证同一时间只有一个线程在执行 Python 字节码。使得 py 写得非常简单方便好理解。


为什么会导致性能问题?

  • 单核限制:即使你在多核 CPU 上启动多个 Python 线程执行计算,由于 GIL 的存在,这些线程在同一时刻也只能使用一个 CPU 核心,无法实现真正的多核并行计算
  • 频繁上下文切换:当一个线程在执行时,如果遇到 I/O 操作或达到执行时间片,它会释放 GIL。此时其他线程会去争抢 GIL,这种频繁的“加锁、释放、线程调度”会产生额外的 CPU 开销,让多线程在 CPU 密集型任务中不仅不提速,反而可能比单线程更慢
  • 对任务类型的影响不同:
    • CPU 密集型任务(如大量数学计算、图像处理):受 GIL 严重影响,多线程性能低下
    • I/O 密集型任务(如网络请求、文件读写):当线程在等待 I/O 时会主动释放 GIL,因此多线程依然能发挥较好效果

解决或绕过 GIL 性能问题

  • 使用多进程(multiprocessing):
    • 通过创建多个独立的进程来绕过 GIL。每个进程都有独立的 Python 解释器和内存空间,能够完全利用多核 CPU 的计算能力
  • 使用 C 扩展(C-Extensions):
    • 像 NumPy、Pandas 等底层由 C/C++ 实现的库,在执行核心计算时会主动释放 GIL,从而实现真正的多线程并行。所以很多应用高层 py,底层依旧是其他语言
  • 异步编程(asyncio):
    • 适用于高并发的 I/O 密集型任务,通过单线程事件循环(Event Loop)避免了多线程带来的线程切换与锁竞争开销
  • 尝试无 GIL 构建版本(Free-Threading,PEP 703):
    • 从 Python 3.13 开始,官方引入了实验性的无 GIL(Free-threaded) 构建版本(安装时可通过 --disable-gil 启用),允许真正的多线程多核并行