1)Python、Ruby 或 Haskell 支持真正的多线程吗?
2)如果程序包含线程,虚拟机是否会自动将工作分配给多个核心(或者如果主板上有多个 CPU,则分配到物理 CPU 上)?
"真正的多线程" 指的是:多个独立的执行线程利用多个核心提供的资源(而不仅仅是一个核心)。
"伪多线程" 是指:线程模拟多线程环境,而无需依赖任何本地操作系统功能。
1) Python、Ruby或Haskell是否支持真正的多线程?
这与编程语言本身无关,而是与硬件有关(如果计算机只有一个 CPU,则同时执行两条指令在物理上是不可能的)、操作系统有关(同样地,如果操作系统不支持真正的多线程,则你什么也做不了)以及语言实现/执行引擎有关。
除非编程语言明确禁止或强制使用真正的多线程,否则这与编程语言本身完全没有关系。
你提到的所有编程语言,以及之前答案中提到的所有编程语言,都有多个实现版本,其中一些支持真正的多线程,一些不支持,并且一些是建立在其他执行引擎之上,这些引擎可能支持或不支持真正的多线程。
以 Ruby 为例,以下是它的一些实现版本和它们的线程模型:
另请参阅我对Ruby的另一个相似问题的回答。(请注意,那个答案已经超过一年了,其中有些内容已经不再准确。例如,现在Rubinius使用真正的并发本地线程,而不是真正的并发绿色线程。此外,自那时以来,出现了几个新的Ruby实现,如BlueRuby、tinyrb、Ruby Go Lightly、Red Sun和SmallRuby。)
对于Python也是类似情况:
对于Haskell,至少GHC(Glorious Glasgow Haskell Compiler)支持使用本地线程实现真正的多线程。我不知道UHC、LHC、JHC、YHC、HUGS或其他所有实现的情况。
对于Erlang,BEAM和HiPE都支持使用绿色线程实现真正的多线程。
2)如果程序包含线程,虚拟机是否会自动分配任务到多个核心(或者如果主板上有多个CPU,则分配到物理CPU)?
同样地:这取决于虚拟机、操作系统和硬件。此外,上述一些实现甚至没有虚拟机。
thread.c
,你可以看到 YARV 经历或将经历的三种不同线程模型的描述:绿色线程 -> 带 GIL 的本地线程 -> 真正的并行本地线程,带有细粒度锁定。然而,目前还没有代码。在 CPython 中,情况类似:Unladen Swallow 计划移除 GIL,并且如果不会太过侵入性,将这个移除贡献回 CPython。 - Jörg W MittagHaskell实现GHC支持在共享内存多核上并行执行的多种机制。这些机制在“《为多核Haskell提供运行时支持》”中进行了描述。
具体而言,Haskell运行时将工作划分为N个操作系统线程,并分布在可用的计算核心上。这些N个操作系统线程又运行M个轻量级的Haskell线程(有时会有数百万个线程)。反过来,每个Haskell线程都可以从一个火花队列中获取工作(可能有数十亿个火花)。就像下面这样:
运行时安排工作在不同的核心上执行,迁移工作并负载平衡。垃圾收集器也是并行的,使用每个核心来收集堆的一部分。
与Python或Ruby不同,Haskell没有全局解释器锁,因此出于这个原因等等,与其他语言相比,在多核上,例如Haskell和Python在多核 shootout 中的比较,GHC表现尤为出色。
如果你使用-threaded
选项进行编译,并在运行时传递+RTS -N<x> -RTS
,其中<x>
表示你想要的操作系统线程数,那么GHC编译器将在多个操作系统线程(因此多个内核)上运行你的程序。
目前的 Ruby 1.9 版本(基于 C 的 YARV 版本)具有原生线程,但存在 GIL 问题。据我所知,Python 也存在 GIL 问题。
然而,Jython 和 JRuby(Ruby 和 Python 的成熟 Java 实现)都提供原生多线程,没有绿色线程,也没有 GIL。
不清楚 Haskell 的情况。
如果你想要真正的并发性,你可能想尝试一下 Erlang。
Haskell 可以用于任何事情。
Python 有 processing
模块,它(我认为 - 不确定)有助于避免 GIL 问题。(因此它也适用于任何事情)。
但是我的观点是,对于大型和巨大的项目,最好选择具有静态类型系统的最高级别语言。今天这些语言是:ocaml、haskell、erlang。
如果你想开发小东西 - Python 是不错的选择。但当事情变得更加复杂时 - 所有 Python 的优点都被无数的测试所消耗。
我没有使用过 Ruby。我仍然认为 Ruby 是一种玩具语言。(或者至少在你知道 Python 的情况下,没有理由去学习 Ruby - 最好读 SICP 书)。