什么是Python全局解释器锁GIL(Global Interpreter Lock)?
一、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),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。
猜你喜欢LIKE
相关推荐HOT
更多>>call和apply区别?
一、call和apply区别apply:非常多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,...详情>>
2023-10-20 21:29:16OC中协议和多态有什么区别?
一、OC中协议和多态的区别在Objective-C中,协议(Protocol)和多态(Polymorphism)是两个不同的概念,它们的区别如下:协议(Protocol):协...详情>>
2023-10-20 20:24:31Android开发中为什么很少使用JSON存储数据?
一、Android开发中为什么很少使用JSON存储数据因为数据库我可以对它进行设计,按照我要的格式来搭建,我可以随时新增一条数据,查询一条数据,...详情>>
2023-10-20 19:17:07为什么Java后端开发没有大规模采用 Kotlin?
一、为什么Java后端开发没有大规模采用 Kotlin以下是我和我的同事们看到的一些原因。“我们没有时间学习一门新语言”这也就是我们在软件开发项...详情>>
2023-10-20 14:03:28热门推荐
公共数据和政务数据有什么区别?
沸流式计算和实时计算有什么区别?
热managed runtime与非managed runtime有什么区别?
热css和html的区别?
新call和apply区别?
顺序表和数组有什么区别?
OC中协议和多态有什么区别?
git的fetch和pull区别?
Android开发中为什么很少使用JSON存储数据?
goal, mission, vision, objective, result和aim之间有什么区别?
什么是php扩展?
为什么插件化对Android开发人员如此重要?
PHP从入门到高级需要掌握什么?
什么是算法?