注意, 这是一篇摘抄文, 仅记录一些概念跟规范
原文出处理解Python中GIL锁
原文出处What Is the Python Global Interpreter Lock(GIL)
全局解释锁(Global Interpreter Lock, 简称GIL), 顾名思义, 它就是一把互斥锁(或是一种锁), 它的作用就是只允许一个线程拥有python解释器的控制权
这就意味着在任何时间点上, 只有一个线程处在可执行的状态(运行时). 对于只执行单线程程序的开发者而言, GIL锁并不会带来什么影响, 但对于密集型CPU和多线程代码却会带来性能瓶颈.
因为在多核多线程的机器上, GIL锁每个时段只允许一个线程执行, , GIL锁也获得到一个臭名昭著的称号”
在这篇文章中, 你将了解到GIL锁是如何影响你python程序的性能. 以及如何降低它对你代码的影响
GIL锁为Python解决了什么问题?
Python采用引用计数的内存管理. 它的作用是追踪一个被创建的对象被引用的次数. 当它的次数为0时, 这个对象所占用的内存会被回收.
让我们看看这段代码来证明引用计数的工作方式.
1 | import sys |
在上面的代码中, 空列表的引用计数为3, 其中, 变量a, b和传递给sys.getrefcount()的实参引用了这个空列表.
回到GIL锁:
如果没有GIL锁, 遇到的问题是, 这个引用变量需要避免出现像两个线程同时对该引用计数进行加或减的条件竞争. 如果发生这种情况, 那么就会出现内存泄漏, 甚至是出现错误, 比如错误的释放内存尽管这个引用对象的变量还存在. 这会出现程序崩溃或其他奇怪的bug
通过加锁, 可以避免多个线程中对整个数据结构出现的不一致情况, 使得引用计数变量更加安全.
但加锁给一个或一组对象意味着存在多把锁, 导致引发另一个问题, 死锁(死锁只会发生在存在多把锁). 因为线程需要不停获取或释放锁, 它的另一个负面影响则是会降低程序执行的效率.
GIL锁是一把单锁, 解释器给自己立下一个了一个规则: 执行任何Python字节码都需要获取解释器锁(GIL锁). 这就避免了死锁(因为只存在一把锁), 并且不会引入太多的性能开销.
但在多核多线程环境下, python程序也只是一个单线程程序.
未完..