GIL锁P并不是Python特有的特性,它只是在实现CPython解释器时引入的概念而已。的定义如下:8-1.png
根据上面的定义可知,GIL是一个互斥锁(mutex)。它可以做到防止多个线程同时执行Python字节码,从而降低执行效率。要了解GIL的必要性,就需要了解CPython对线程安全的内存管理机制。
CPython对线程安全的内存管理机制
Python使用引用计数进行内存管理,Python中创建的对象都有一个引用计数,记录指向它的指针数量。如果参考计数的值是0时,内存将被自动释放。
让我们看一个小例子,解释引用计数的原理。
>>>import sys
>>>a=[]
>>>b=a
>>>sys.getrefcount(a)
可见a的引用计数值是3,因为传递给a、b和作为参数传递的getrefcount都引用了一个空列表。
假如有2个python线程同时引用a,那么2个线程都将试图处理它的数据,多个线程将同时处理一个数据,如果出现了这样的情况,将导致内存泄漏。
GIL锁的产生
Cpython创建了GIL锁,这是因为多个线程同时操作数据,从而引发数据不一致,导致内存泄漏,因此我们可以将它加锁。
由于有了锁,一个对象需要一个锁,所以多个对象就需要有多个锁,这可能会造成两个问题。
1.死锁(线程之间争夺锁的资源)
2.反复获取和释放锁会导致性能下降。
为了增加单线程情况下python的正常执行和效率,GIL锁(单一锁)由此产生了,它增加了一条规则,即任何Python字节码的执行都需要获得解释器锁。
这防止了死锁(因为只有一个锁),而且没有太大的性能开销。
但是与此同时也造成的另一种情况,这实际上使得所有受CPU约束的Python程序(CPU密集型程序)都是单线程的。