Python、Ruby、Haskell - 它们提供真正的多线程吗?

16 投票
8 回答
7333 浏览
提问于 2025-04-15 17:07

我们计划用一些高级编程语言来写一个高并发的应用程序。

1) Python、Ruby 或 Haskell 这些语言支持真正的多线程吗?

2) 如果一个程序里有线程,虚拟机会自动把工作分配到多个核心上吗(或者如果主板上有多个物理 CPU 的话)?

真正的多线程 = 多个独立的执行线程利用多个核心提供的资源(而不是只用一个核心)。

伪多线程 = 线程模拟多线程环境,但不依赖任何操作系统的原生功能。

8 个回答

16

如果你在编译程序时使用了 -threaded 这个选项,GHC 编译器就会让你的程序在多个操作系统线程上运行,也就是可以同时使用多个核心。然后在运行程序的时候,你需要加上 +RTS -N<x> -RTS 这个参数,其中 <x> 是你想要使用的线程数量。

22

Haskell的实现版本GHC支持多种在共享内存多核处理器上并行执行的方式。这些方式在“多核Haskell的运行时支持”中有详细介绍。

具体来说,Haskell的运行时会把工作分配给N个操作系统线程,这些线程会分布在可用的计算核心上。这N个操作系统线程又会运行M个轻量级的Haskell线程(有时候可能会有数百万个)。每个Haskell线程可以从一个叫做“火花队列”的地方获取工作(这个队列里可能有数十亿个火花)。就像这样:

enter image description here

运行时会安排工作在不同的核心上执行,还会迁移工作和进行负载均衡。垃圾回收器也是并行的,它会利用每个核心来收集一部分内存。

与Python或Ruby不同,Haskell没有全局解释器锁,因此在多核处理上,GHC表现得特别好,比如在多核性能对比中,Haskell与Python的比较

34

1) Python、Ruby 或 Haskell 支持真正的多线程吗?

这个问题跟编程语言本身没关系,主要是看硬件(如果机器只有一个 CPU,那就不可能同时执行两条指令),操作系统(如果操作系统不支持真正的多线程,那也没办法)以及语言的实现和执行引擎。

只要语言规范没有明确禁止或强制要求真正的多线程,这个问题就和语言本身无关。

你提到的所有语言,以及到目前为止回答中提到的所有语言,都有多种实现方式,其中一些支持真正的多线程,有些则不支持,还有一些是基于其他执行引擎的,这些引擎可能支持也可能不支持真正的多线程。

以 Ruby 为例,这里列出一些它的实现和它们的线程模型:

  • MRI:绿色线程,不支持真正的多线程
  • YARV:操作系统线程,不支持真正的多线程
  • Rubinius:操作系统线程,支持真正的多线程
  • MacRuby:操作系统线程,支持真正的多线程
  • JRuby、XRuby:JVM 线程,取决于 JVM(如果 JVM 支持真正的多线程,那么 JRuby/XRuby 也支持;如果不支持,那它们也无能为力)
  • IronRuby、Ruby.NET:和 JRuby、XRuby 类似,但在 CLI 上运行,而不是在 JVM 上

你可以查看我对 Ruby 相关问题的另一个回答(注意那是超过一年前的回答,有些内容可能不再准确。例如,Rubinius 现在使用真正的本地线程,而不是之前的绿色线程。此外,自那以后,出现了几种新的 Ruby 实现,比如 BlueRuby、tinyrb、Ruby Go Lightly、Red Sun 和 SmallRuby)。

Python 的情况类似:

  • CPython:本地线程,不支持真正的多线程
  • PyPy:本地线程,取决于执行引擎(PyPy 可以本地运行,也可以在 JVM、CLI 或其他 Python 执行引擎上运行。只要底层平台支持真正的多线程,PyPy 也支持)
  • Unladen Swallow:本地线程,目前不支持真正的多线程,但计划修复
  • Jython:JVM 线程,参考 JRuby
  • IronPython:CLI 线程,参考 IronRuby

对于 Haskell,至少 Glorious Glasgow Haskell Compiler 支持使用本地线程的真正多线程。我对 UHC、LHC、JHC、YHC、HUGS 或其他实现不太了解。

对于 Erlang,BEAM 和 HiPE 都支持使用绿色线程的真正多线程。

2) 如果一个程序包含线程,虚拟机会自动将工作分配到多个核心(或者如果主板上有多个 CPU,就分配到物理 CPU)吗?

这同样取决于虚拟机、操作系统和硬件。此外,上面提到的一些实现甚至没有虚拟机。

撰写回答