Python新提案:“废除”全局解释器锁GIL|CPython解释器可能变得更快大语言问题——“废除”Python语言的全局解释器锁(GIL)。“双刃剑”:CPython——解释器和编译器众所周知,Python动态语言的灵活性是一把“双刃剑”。这意味着可以有不同的运行时,例如Pyston、Cinder、MicroPython、pypypy等,它们可能支持整个语言、特定版本或子集。但如果您使用的是Python,那么您可能正在运行CPython。CPython是用C编写的标准Python解释器,它也充当编译器,因为它的工作是在实际解释阶段之前将Python代码编译成字节码。CPython有一个叫做全局解释器锁GIL(GlobalInterpreterLock)的东西,它可以影响线程代码,即解释器中一次只能运行一个线程。因此,GIL一直被视为语言发展的固有限制。此前,已经有人提出解决这个问题的建议,比如将性能关键的部分移到C或者使用多个解释器。但要满足上述期望,口译员用户的受众可能会扩大。有几种替代方案,例如通过专用的JVM(Java虚拟机)和CLR(公共语言运行时),但大多数上述现有解决方案都有相当大的缺点。因此,基于上述背景,支持“没有全局解释器锁的Python”的声音逐渐受到关注。多次尝试废除:如何废除GIL直到本次Python语言峰会,Meta高级工程总监SamGross在“nogil”项目的主题中提出了“废除GIL”的话题。据悉,该提案是基于此前废除Python中GIL的想法。Gross最初在使用第三方代码的Python项目中遇到问题,因此他开始考虑如何“在没有GIL的情况下”实现线程安全。如前所述,全局解释器锁(GIL)一次只能在解释器中运行一个线程,因此程序状态可能更容易推断何时可以保证一次只有一个线程在运行。但是如果没有GIL,引用计数、内存分配、方法解析顺序缓存和垃圾收集线程就会变得不安全。那么,如何摆脱GIL?据报道,SamGross早些时候专门讨论了这种演变。CPython的设计是“线程安全的”,但它依赖于GIL。摆脱GIL始于对引用计数的重大改变。为了知道垃圾收集器是否可以释放内存中的对象,它会统计对该对象的所有引用。目前引用计数是非原子的,将所有引用计数操作更改为原子操作会对性能产生巨大影响。SamGross在该提案中使用了一种称为“偏向引用计数”的技术来获取本地和共享引用。本地引用可以利用非原子操作,拥有线程结合本地和共享引用来跟踪所有权。这种方法适用于单线程对象,或者只被少数线程少量使用的对象。在程序的生命周期中存在的几个对象,例如内插字符串、True、False和None,可以标记为“不朽”,从而将它们的引用计数开销减少到零。通过使用引用计数字段中的最低有效位,对象被标记为“不朽”。被频繁访问但不保证“不朽”的对象具有延迟引用计数,这意味着唯一需要的引用计数是在引用存储在堆上时。剩余引用。SamGross用mimalloc替换了标准的pymalloc内存分配器,mimalloc是提供线程安全和性能的malloc的替代品。这种交换的好处是,这个分配器允许运行时在没有显式列表的情况下查找GC跟踪的对象。这是一个显着的性能提升,但这意味着您不能只换入另一个与malloc兼容的分配器并期望与垃圾收集和收集相同的线程安全性。Python尚未决定是否移除GIL对于移除GIL的原因,Python基金会博客解释说,“为了让Python在没有GIL的情况下有效地工作,必须在大部分代码中添加新的锁以确保它仍然是线程安全的,但向现有代码添加新锁可能非常困难,因为在某些领域可能会出现显着的减速。”这一次,SamGross提出的“移除GIL”的新提议似乎得到了Python核心开发团队其他成员的一致好评。来自会员的“热烈”欢迎。现在,要解决的主要问题是如何在CPython中实现如此剧烈的变化。据悉,下一个版本的CPython(或CPython3.11)预计在2022年10月发布,不知道届时是否会有重大更新,但据悉开发者特别希望获得更高的性能以及与此更新的兼容性。支持在Web浏览器上下文中运行的集成。在过去的一段时间里,开发人员多次尝试在标准实现CPython中取消这项技术,因为GIL阻碍了语言的进步。这一次,“去除GIL”的新提议终于来了。虽然Python官方还没有最终决定具体实现,但一切还是值得期待的。
