我希望有人可以提供一些关于 Java 虚拟机的根本不同之处的见解,它允许它很好地实现线程而不需要全局解释器锁 (GIL),而 Python 需要这样一个邪恶。
5 回答
Python(语言)不需要 GIL(这就是为什么它可以完美地在 JVM [Jython] 和 .NET [IronPython] 上实现,并且这些实现可以自由地多线程)。CPython(流行的实现)一直使用 GIL 来简化编码(尤其是垃圾收集机制的编码)和非线程安全的 C 编码库的集成(过去有很多这样的库; -)。
除了其他雄心勃勃的目标外,Unladen Swallow 项目确实为Python计划了一个无 GIL 虚拟机——引用该网站的话,“此外,我们打算删除 GIL 并修复 Python 中的多线程状态。我们相信这是可以通过实施更复杂的 GC 系统来实现,例如 IBM 的 Recycler(Bacon 等人,2001 年)。”
JVM(至少是热点)确实与“GIL”有类似的概念,它的锁粒度要细得多,其中大部分来自更高级的热点中的GC。
在 CPython 中,它是一个大锁(可能不是那么正确,但对于争论来说已经足够好了),在 JVM 中,它更多地散布在不同的概念上,具体取决于它的使用位置。
例如,看一下热点代码中的 vm/runtime/safepoint.hpp,它实际上是一个障碍。一旦到达安全点,整个 VM 就 java 代码停止了,就像 python VM 停止在 GIL 一样。
在 Java 世界中,这种 VM 暂停事件被称为“stop-the-world”,在这些点上,只有绑定到特定标准的本机代码才能自由运行,其余的 VM 已停止。
此外,Java 中缺少粗锁使得 JNI 更难以编写,因为 JVM 对其 FFI 调用环境的保证较少,这是 cpython 相当容易的事情之一(尽管不如使用 ctypes 容易)。
在这篇博文http://www.grouplens.org/node/244下方有一条评论,暗示了为什么 IronPython 或 Jython 可以如此轻松地免除 GIL,这是因为 CPython 使用引用计数,而其他 2 个虚拟机有垃圾收集器。
我不明白为什么会这样的确切机制,但这听起来确实是一个合理的理由。
Python 缺少 jit/aot 并且它在多线程处理器上编写的时间框架不存在。或者,您可以在缺少 GIL 的 Julia lang 中重新编译所有内容,并在您的 Python 代码上获得一些速度提升。Jython 也有点糟糕,它比 Cpython 和 Java 慢。如果您想坚持使用 Python,请考虑使用并行插件,您不会立即获得速度提升,但您可以使用正确的插件进行并行编程。