为什么Java虚拟机没有GIL?Python为何如此需要它?

188 投票
5 回答
20790 浏览
提问于 2025-04-15 12:14

我希望有人能解释一下,Java虚拟机和Python之间有什么根本的区别,让Java可以很好地实现线程,而不需要一个叫做全局解释器锁(GIL)的东西,而Python却必须要有这个东西。

5 个回答

7

在这个博客帖子下面有一个评论,提到为什么在IronPython或Jython中可以轻松去掉GIL(全局解释器锁)。原因是CPython使用的是引用计数,而另外两个虚拟机(VM)则使用垃圾回收机制。

我不太明白具体的原理,但听起来这个理由是有道理的。

56

JVM(至少是热点版本)有点像“全局解释器锁”(GIL)的概念,只不过它的锁定方式更细致。大部分原因是热点中的垃圾回收(GC)技术更先进。

在CPython中,基本上是一个大锁(虽然这不完全准确,但为了讨论方便可以这么理解),而在JVM中,锁的使用更分散,具体取决于使用的场景。

比如说,可以看看热点代码中的vm/runtime/safepoint.hpp,这实际上是一个屏障。一旦到达一个安全点,整个虚拟机在处理Java代码时就会暂停,这就像Python虚拟机在GIL处于活动状态时会停止一样。

在Java的世界里,这种虚拟机暂停的事件被称为“世界停止”,在这些时刻,只有符合特定条件的本地代码可以继续运行,其他的虚拟机部分都被暂停了。

此外,Java中没有粗粒度的锁,这让JNI(Java Native Interface)变得更难编写,因为JVM对其环境在外部函数调用(FFI)方面的保证较少,而CPython在这方面相对简单(虽然比起使用ctypes还是有点复杂)。

230

Python 这门语言本身并不需要全局解释器锁(GIL),这也是为什么它可以在 JVM(Java 虚拟机)上完美运行(比如 Jython)和在 .NET 上运行(比如 IronPython),而这些实现可以自由地使用多线程。

而 CPython(最流行的 Python 实现)一直使用 GIL,主要是为了让编码更简单,特别是在处理垃圾回收机制时,以及与那些不支持多线程的 C 语言库的整合(以前有很多这样的库)。

有一个叫做 Unladen Swallow 的项目,它有很多雄心勃勃的目标,其中之一就是计划为 Python 创建一个没有 GIL 的虚拟机——网站上提到:“此外,我们打算去掉 GIL,并改善 Python 的多线程状态。我们相信这可以通过实现一个更复杂的垃圾回收系统来实现,类似于 IBM 的 Recycler(Bacon 等,2001 年)。”

撰写回答