• 首页
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案
目录

什么是Python全局解释器锁GIL(Global Interpreter Lock)

简单来说,Python全局解释器锁 ( Global Interpreter Lock )或 GIL 是一个互斥锁,它只允许一个线程来控制Python解释器。这意味着在任何时间点只有一个线程可以处于执行状态。执行单线程程序的开发人员感受不到GIL的影响。

一、Python全局解释器锁GIL(Global Interpreter Lock)

简单来说,Python全局解释器锁(Global Interpreter Lock)或GIL是一个互斥锁,它只允许一个线程来控制Python解释器。

这意味着在任何时间点只有一个线程可以处于执行状态。执行单线程程序的开发人员感受不到GIL的影响,但它可能是CPU限制型和多线程代码中的性能瓶颈。

由于即使在具有多个CPU核心的多线程架构中,GIL一次只允许一个线程执行,因此GIL已经成为Python“臭名昭着”的特性。

GIL为Python解决了什么问题

Python使用引用计数进行内存管理。这意味着在Python中创建的对象具有引用计数变量,该变量用于跟踪指向该对象的引用数。当此计数达到零时,释放对象占用的内存。

让我们看一个简短的代码示例来演示引用计数的工作原理:

>>> 

>>> import sys

>>> a = []

>>> b = a

>>> sys.getrefcount (a)

3

在上面的示例中,空列表对象的引用计数为3。列表对象由a,b引用并且参数传递给sys.getrefcount()。

回到GIL:

问题是这个引用计数变量需要保护竞争条件。如果其中两个线程同时增加或减少其值,如果发生这种情况,它可能导致从未释放的内存泄漏,或者更糟糕的是,在对该对象的引用仍然存在时错误地释放内存。这可能会导致Python程序中出现崩溃或其他“怪异”错误。通过向跨线程共享的所有数据结构添加锁,可以保持此引用计数变量的安全性,从而不会对它们进行不一致的修改。

但是为每个对象或对象组添加一个锁意味着将存在多个锁,这可能导致另一个问题 – 死锁(死锁只有在有多个锁时才会发生)。另一个副作用是由于重复获取和释放锁而导致性能下降。

GIL是解释器本身的单个锁,它增加了一条规则,即执行任何Python字节码都需要获取解释器锁。这可以防止死锁(因为只有一个锁)并且不会引入太多的性能开销。但它有效地使任何受CPU限制的Python程序都是单线程的。

GIL虽然被解释器用于其他语言(如Ruby),但并不是解决此问题的少数方法。有些语言通过使用除引用计数之外的方法(例如垃圾收集)来避免GIL对线程安全内存管理的要求。

另一方面,这意味着这些语言通常需要通过添加其他性能提升性能(如JIT编译器)来弥补GIL单线程性能优势的损失。

为什么选择GIL作为解决方案

那么,为什么在Python中使用的方法看似如此阻碍呢?这是Python开发人员的糟糕决定吗?

好吧,用Larry Hastings的话来说, GIL的设计决定是让Python像今天一样受欢迎的原因之一。

自从操作系统没有线程概念以来,Python就已存在。Python的设计易于使用,以便更快地开发,越来越多的开发人员开始使用它。

开发人员正在为Python需要的功能编写许多C库扩展。为了防止不一致的更改,这些C扩展需要GIL提供的线程安全内存管理。

GIL易于实现,很容易添加到Python中。它为单线程程序提供了性能提升,因为只需要管理一个锁。

非线程安全的C扩展变得更容易集成。这些C扩展成为不同社区愿意采用Python的原因之一。

正如您所看到的,GIL是一个实用的解决方案,可以解决CPython开发人员在Python生命中早期面临的一个难题。

对多线程Python程序的影响

当您查看典型的Python程序或任何计算机程序时,那些在性能上受CPU限制的程序与受I / O限制的程序之间存在差异。

CPU绑定程序是那些将CPU推向极限的程序。这包括进行数学计算的程序,如矩阵乘法,搜索,图像处理等。

I / O绑定程序是花费时间等待输入/输出的程序,它可以来自用户,文件,数据库,网络等。I / O绑定程序有时需要等待很长时间才能完成从源获取他们需要的东西,因为源可能需要在输入/输出准备好之前进行自己的处理,例如,用户考虑输入什么输入提示或在其中运行的数据库查询自己的过程。

延伸阅读:

二、什么是Python

Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。

相关文章