当前位置: 首页 > 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.lryc.cn/news/608534.html

相关文章:

  • 如何在`<link type=“icon“ href=`的`href`中写SVG并使用path标签? 笔记250802
  • C++:std::array vs 原生数组 vs std::vector
  • 通俗易懂解释Java8 HashMap
  • 计数组合学7.11(RSK算法)
  • 人工智能与农业:智慧农业的发展与未来
  • 数据集-目标检测系列- 地球仪 数据集 globe>> DataBall
  • SmartCLIP:具有识别保证的模块化视觉-语言对齐
  • 代码随想录刷题Day23
  • linux 启动流程?
  • 拉格朗日插值法
  • 数据库理论
  • 深入 Go 底层原理(七):逃逸分析
  • 商品中台数据库设计
  • Flutter dart运算符
  • 【Leetcode】2561. 重排水果
  • 嵌入式第十八课!!数据结构篇入门及单向链表
  • 数据结构(12)二叉树
  • 计算学习理论(PAC学习、有限假设空间、VC维、Rademacher复杂度、稳定性)
  • Java内存模型(Java Memory Model,JMM)
  • 网安-中间件-weblogic(updating..)
  • 数据结构初学习、单向链表
  • 暑期算法训练.13
  • 什么是DOM和BOM?
  • 智能手表:电源检查
  • 入门MicroPython+ESP32:安装逗脑IDE及驱动
  • JVM 03 类加载机制
  • 堆----1.数组中的第K个最大元素
  • 高效游戏状态管理:使用双模式位运算与数学运算
  • 关于人工智能AI>ML>DL>transformer及NLP的关系
  • springboot大学生成绩管理系统设计与实现