并行线程 python GIL 与 Java

Parallel threading python GIL vs Java

我知道 python 有一个 GIL 使线程不能同时 运行 因此线程只是上下文切换。

为什么 java 不同? 每种语言中相同 CPU 的线程不能 运行 并行。

  1. 在 java 中创建新线程是否利用了多核机器中的内核?

  2. python 只能在同一个 CPU 上生成线程,与 java?

    形成对比
  3. 如果 1. 是这种情况,当使用多于 CPU 的线程时,即使在 java 中,其中几个线程又回到上下文切换?

  4. 如果1.是这种情况那么它与多处理有何不同?因为不能保证使用多核?

  5. 线程的全部意义不就是能够使用相同的内存吗space?如果 java 在多个线程中执行 运行 其中一些以实现并行性,那么它们如何真正共享内存?

谢谢

Why is java different?

因为它能够有效地同时使用多个内核。


  1. Does creating a new thread in java utilizes cores in multi core machine?

是的。


  1. Python can only spawn threads on the same CPU, in contrast to Java?

Java 可以生成多个线程,这些线程将在不同的 CPU 上。 Java 不负责实际的线程调度。这是由 OS 处理的。 OS 可能会将一个线程重新安排到另一个 CPU 与其开始的线程。

我不确定 Python 的确切细节,但我认为 GIL 是一个实现细节,而不是语言本身固有的东西1 .但无论哪种方式,在 Python 实现中,GIL 都意味着您在多核上生成线程时几乎不会获得性能优势。正如 this page 所说:

"The Python Global Interpreter Lock or GIL, in simple words, is a mutex (or a lock) that allows only one thread to hold the control of the Python interpreter."


  1. If 1. is the case, when using more threads than CPUs does it come back to context switching in Java?

视情况而定。在属于不同进程的线程之间切换 CPU 时,涉及到完整的上下文切换。但是在同一个进程的线程之间切换时,只需要切换(用户)寄存器​​即可。 (虚拟内存寄存器和缓存不需要切换/刷新,因为线程共享相同的虚拟地址space。)


  1. If 1. is the case then how is it differ from multiprocessing? Because utilizing multiple cores isn't guaranteed?

multi-threading 和 multi-processing 之间的主要区别是进程不共享任何内存。相比之下,一个进程中的一个线程可以看到所有其他线程的内存... 变化可见时的模数问题。

这种差异会产生多种后果。


  1. Isn't the whole point of threading is being able to use the same memory space?

是的,这就是重点......当你将 multi-threading 与 multi-processing 进行比较时。

If Java does run some of them in multiple threads for parallelism ...

Java 出于多种原因支持线程。并行性只是其中一个原因。其他包括多路复用 I/O 和简化某些类型的编程问题。这些其他原因也与 Python.

有关

... how do [Java threads] really share memory?

硬件处理使物理内存对所有线程可见以及通过内存缓存传播更改的问题。很复杂。


在 Java 中,当线程使用共享变量/对象时,程序员有责任“做正确的事”。您需要使用 volatile 变量,或 synchronized 块/方法,或其他确保在写入和后续读取之间存在 happens before 链的其他东西。 (否则您可能会遇到更改不可见的问题。)

这种将责任转移给程序员的方式允许编译器生成具有更少主内存操作的代码……因此速度更快。不利的一面是,如果应用程序不遵守规则,它可能会以意想不到的方式运行。

相比之下,在 Python 中,内存模型未指定,但有一个 期望 (数百万 Python 程序员)它将表现以直观的方式;也就是说,一个线程执行的共享变量写入将立即对其他线程可见。这很难有效地实现,同时还允许 Python 线程并行 运行。


1 - 虽然 GIL 不是 Python 规范的正式组成部分,但 GIL 对(未指定!)Python 内存模型和 Python 程序员的假设使其不仅仅是 仅仅是 一个实现细节。 Python 能否成功演化成 multi-threading 可以使用多核 有效 .

的语言还有待观察

这里不是一个完整的答案,只是添加了一些 Stephen C 没有说过的事情:

  1. Python can only spawn threads on the same CPU, in contrast to java?

那将是一种优化,而不是必要的事实。原则上没有理由为什么 Python 不能简单地允许 OS 在任何给定时间恰好可用的任何 CPU 上安排它的线程。

OTOH,考虑到没有两个 Python 线程可以同时完成大量工作,如果线程都具有 affinity 相同的 CPU,则可能会提高性能。 (请参阅 Stephen C 所说的“完全上下文切换”与“仅(用户)注册”。

让 user-mode 进程控制处理器关联是某些操作系统中的一个相对较新的功能。我不知道是否有 Python 版本实际使用了该功能。

  1. If java does run...multiple threads for parallelism...?

Java 不“运行 多线程并行。” 您的 Java 程序 出于某种原因创建了多个线程 恰好需要它们。大多数现代 OS 都提供线程。 Java 只是以与语言本身紧密集成的方式使应用程序程序员可以使用该功能。您可以随意使用(或不使用)它们,但您认为合适。