当前位置: 首页 > news >正文

Python 全局解释器锁

什么是 GIL?

GIL 是 CPython 解释器中的一个互斥锁。它确保在任何给定时刻,只有一个线程可以执行 Python 字节码

简单来说,即使你的计算机有多个 CPU 核心,CPython 解释器也强制所有的 Python 线程在一个进程中轮流执行,一次只能有一个线程运行 Python 代码

为什么需要 GIL?

GIL 最初被引入主要是为了解决以下两个关键问题:

  • 内存管理(引用计数):CPython 使用 引用计数作为其主要的垃圾回收机制。每个对象都有一个引用计数,当计数变为零时,对象就会被释放。引用计数的增减必须是原子操作,否则在多线程环境下,多个线程同时修改同一个对象的引用计数会导致竞态条件,从而引发内存泄漏或程序崩溃。GIL 提供了一个简单而有效的全局锁来保护这些操作,避免了在每个引用计数操作上都加细粒度锁的复杂性和性能开销
  • 简化解释器实现:移除 GIL 会使 CPython 解释器的内部实现变得及其复杂。开发者需要解释器内部的每一个数据结构和操作在多线程环境下都是线程安全的,这会大大增加开发和维护的难度。

GIL 的影响

GIL 的存在带来了显著的利弊

主要缺点:

  • 限制多线程 CPU 密集型任务的并行性:这是 GIL 最受诟病的地方。如果你的程序是 CPU 密集型的(例如进行大量数学计算、数据处理、图像处理等),并且你试图使用多线程来并行化,那么 GIL 会成为瓶颈。因为所有线程都无法真正并行执行 Python 字节码,它们会被迫轮流执行,导致多线程版本可能比单线程版本还要慢(由于线程切换开销),或者性能提升非常有限,无法充分利用多核 CPU。

主要优点/缓解因素:

  • I/O 密集型任务不受影响:对于 I/O 密集型任务(如文件读写、网络请求、数据库操作),线程在等待 I/O 操作完成时会释放 GIL。这意味着其他线程可以在此期间运行。因此,在处理大量 I/O 操作时,多线程仍然非常有效,可以显著提高程序的吞吐量和响应速度。
  • C 扩展可以释放 GIL:用 C 语言编写的 Python 扩展(如 NumPy, SciPy, Pandas, requests 等)在执行耗时的计算或 I/O 操作时,可以主动释放 GIL。这样,即使 Python 代码在执行这些库的函数,GIL 也被释放了,允许其他 Python 线程运行。这使得这些库在多线程环境下也能实现真正的并行计算(在 C 代码层面)。
  • 单线程性能:由于避免了细粒度锁的开销,单线程程序的性能通常比没有 GIL 但需要大量锁的解释器要好。

如何绕过 GIL 的限制?

如果你需要实现真正的并行计算(尤其是在 CPU 密集型任务中),有几种策略:

  1. 使用 multiprocessing 模块:这是最常用和推荐的方法。multiprocessing 创建的是独立的进程,每个进程都有自己的 Python 解释器和内存空间,因此每个进程都有自己的 GIL。这样就可以充分利用多核 CPU 进行并行计算。进程间的通信可以通过 Queue, Pipe, shared memory 等方式实现。
  2. 使用支持 GIL 释放的库:如前所述,使用 NumPy, Pandas, Cython(编写 C 扩展时主动管理 GIL)等库,它们在底层 C 代码中会释放 GIL。
  3. 使用异步编程(asyncio:对于 I/O 密集型任务,asyncio 提供了基于事件循环的并发模型,通常比多线程更高效,且避免了线程切换的开销。它本质上是单线程的,但通过协程实现了高并发。
http://www.dtcms.com/a/311695.html

相关文章:

  • 如何静态链接 YARA 库,实现免依赖的独立可执行文件部署
  • MySqL(加餐)
  • 代码随想录Day36:动态规划(最后一块石头的重量 II、目标和、一和零)
  • 在线问诊系统源码解析:图文+视频双模式架构开发全攻略
  • 【07】VisionMaster入门到精通——Blob分折
  • IDM下载失败排查
  • 北京-4年功能测试2年空窗-报培训班学测开-今天来聊聊我的痛苦
  • 浪漫温柔的表白
  • 在linux(ubuntu)服务器上安装NTQQ并使用
  • 链表【数据结构】
  • UDP受限广播地址255.255.255.255的通信机制详解
  • 信号产生机制全解析:从硬件异常到软件触发的深度探索
  • sc-atac的基础知识(0)
  • Balabolka软件调用微软离线自然语音合成进行文字转语音下载安装教程
  • 医疗AI中的马尔科夫链深度应用与Python实现
  • Gemini CLI
  • Linux进程间通信——system V信号量
  • linux 启动流程?
  • C++刷题 - 7.27
  • 深度学习-模型初始化与模型构造
  • 元宇宙重构未来交通新图景
  • 对过去一年毕业求职季的简单复盘
  • Gossip 协议
  • 锁相关(AI回答)
  • LeetCode Hot 100:3. 无重复字符的最长子串
  • 学习日志25 python
  • Vue3核心语法基础
  • FFmpeg+javacpp中纯音频播放
  • yolo 、Pytorch (5)IOU
  • 衡石科技实时指标引擎解析:如何实现毫秒级响应万亿级数据的增量计算?