为什么Java虚拟机中没有GIL? 为什么Python需要一个如此糟糕的?

我希望有人能够提供一些洞察力,认为Java虚拟机有什么根本的不同,它允许它在不需要全局解释器锁(GIL)的情况下很好地实现线程,而Python则需要这样一个邪恶的东西。

Python(语言)不需要GIL(这就是为什么它可以完美地在JVM [Jython]和.NET [IronPython]上实现,并且这些实现可以自由multithreading)。 CPython(stream行的实现)总是使用GIL来简化编码(尤其是垃圾收集机制的编码)和整合非线程安全的C编码库(过去曾经有过很多的库, – )。

Unladen Swallow项目以及其他雄心勃勃的目标,确实计划了一个无GIL的Python虚拟机 – 引用该网站:“另外,我们打算删除GIL并修复Python中的multithreading状态,我们相信这是可能通过实施更复杂的GC系统,如IBM的Recycler(Bacon et al,2001)。

JVM(至less是热点)与“GIL”有相似的概念,它的锁粒度要好得多,大部分来自GC在更高级的热点地区。

在CPython中,它是一个大的锁(可能不是那么真实,但是为了争辩而言足够好),在JVM中它更多地使用不同的概念来传播,这取决于它在哪里使用。

例如,在热点代码中查看vm / runtime / safepoint.hpp,这实际上是一个障碍。 一旦处于安全状态,整个虚拟机就停止了Java代码,就像Python虚拟机停在GIL中一样。

在Java世界中,这种虚拟机暂停事件被称为“停止世界”,在这些地方,只有绑定到特定条件的本地代码才会自由运行,虚拟机的其余部分已经停止。

另外,由于缺lessJava的粗略locking,使得JNI难于编写,因为JVM对FFI调用的环境做了较less的保证,cpython变得相当容易(尽pipe不如使用ctypes简单)。

在这个链接中,他们有以下解释:

…“部分解释器不是线程安全的,尽pipe大多数情况下是因为通过大量的锁使用它们全部线程安全会使单线程极其缓慢( 源代码 ),这似乎与使用引用计数的CPython垃圾回收器(JVM而CLR则没有,因此不需要每次都locking/释放引用计数),但即使有人想到一个可接受的解决scheme并实现了它,第三方库仍然会有同样的问题。

Python缺lessjit / aot,并且它在multithreading处理器上写入的时间框架不存在。 或者,您可以重新编译Julia lang中缺lessGIL的所有内容,并在Python代码上获得一些速度提升。 Jython也比Cpython和Java慢。 如果你想坚持Python,考虑使用并行插件,你不会立即获得速度提升,但你可以使用正确的插件进行并行编程。