186

我希望有人可以提供一些关于 Java 虚拟机的根本不同之处的见解,它允许它很好地实现线程而不需要全局解释器锁 (GIL),而 Python 需要这样一个邪恶。

4

5 回答 5

229

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

除了其他雄心勃勃的目标外,Unladen Swallow 项目确实为Python计划了一个无 GIL 虚拟机——引用该网站的话,“此外,我们打算删除 GIL 并修复 Python 中的多线程状态。我们相信这是可以通过实施更复杂的 GC 系统来实现,例如 IBM 的 Recycler(Bacon 等人,2001 年)。”

于 2009-06-14T01:20:55.717 回答
56

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 容易)。

于 2009-07-22T01:27:17.403 回答
7

在这篇博文http://www.grouplens.org/node/244下方有一条评论,暗示了为什么 IronPython 或 Jython 可以如此轻松地免除 GIL,这是因为 CPython 使用引用计数,而其他 2 个虚拟机有垃圾收集器。

我不明白为什么会这样的确切机制,但这听起来确实是一个合理的理由。

于 2010-04-12T21:45:10.603 回答
2

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

...“解释器的某些部分不是线程安全的,尽管主要是因为通过大量使用锁使它们都成为线程安全的会极大地减慢单线程(来源)。这似乎与使用引用计数的 CPython 垃圾收集器有关(JVM而 CLR 则不需要,因此不需要每次都锁定/释放引用计数)。但即使有人想到了一个可接受的解决方案并实施了它,第三方库仍然会遇到同样的问题。

于 2017-06-28T17:02:01.367 回答
-1

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

于 2016-06-20T09:00:57.743 回答