Scala和Erlang使用绿色线程吗?

14

我一直在阅读关于Scala和Erlang如何使用轻量级线程和并发模型(actors)的文章。

但是,我还有些疑问。

Scala和Erlang是否采用与Java旧版线程模型(绿色线程)类似的方法?

例如,假设有一台拥有2个核心的机器,那么Scala/Erlang环境将为每个处理器分配一个线程吗?其他线程将由用户空间(Scala VM / Erlang VM)环境进行调度。这样正确吗?

在底层,这实际上是如何工作的?


Java 十年来一直没有使用绿色线程。 - deprecated
4个回答

24

Erlang使用用户空间多任务处理,任务运行直到它们被阻塞或者使用完它们的“reductions”份额。一个reduction模糊定义为一次计算的单元。

在SMP调度器之前,只有一个内核线程处理可运行任务。通过SMP调度,您可以使用多个内核线程来处理任务,从而在多核机器上并行执行代码。调度线程的数量应该与核心数相匹配。请参阅erl manpage中的-smp [enable|auto|disable]开关。

还有用于执行阻塞系统调用的可加载驱动程序的内核线程池。这称为异步线程池。请参阅erl manpage中的+A size

进一步阅读


谢谢Christian。因此,用户空间的多任务调度程序将选举一些“线程对象”由操作系统线程执行。对吗? - CHAPa
我无法比我链接到的EUC'08的pdf更好地描述它。我相信当前的OTP版本现在具有多个运行队列,如第5.2节所述,我们生活在未来。 - Christian
不,操作系统线程运行的是一个Erlang调度程序,该程序明确处理进程及其调度。这就是为什么你很少会在每个核心上有多个线程,至少对于运行Erlang代码而言,这是不需要的。操作系统线程通常太重,不能用于Erlang进程。 - rvirding

13

Scala 2.8使用Java线程池。轻量级的演员(Reactor)和轻量级模式下的较重的演员(react {...})不会占用自己的线程;相反,当它们有消息时,它们会占用一个线程直到完成处理该消息,然后归还线程并且在下一条消息到来前不运行。

这篇文章描述了2.7版本的演员(Actors)并且对2.8版本也有帮助。


@Rex,但是为了可扩展性,Scala不能仅使用Java线程(本机操作系统线程),它必须能够创建一个新类型的线程环境,例如绿色线程。想象一下,有100个演员,每个演员都使用一个Java线程,这不是轻量级线程,因为切换线程上下文并不轻松,对吧? - CHAPa
这有点正确。开关不像Erlang那样轻量级。你几乎总是可以避免在100个线程上拥有100个actor(通过对消息做出反应而不是不断运行它们),因此您仍然拥有整个事件的非轻量级Java线程,但更轻量级的消息消耗(因为多个actor的消息可以由一个线程处理)。由于这种架构,您可以扩展到非常多的反应式actor而不会用尽操作系统线程,但它并不像Erlang那样具有惊人的可伸缩性。(搜索“线程环基准测试大比拼”...) - Rex Kerr
@CHAPa Akka actors基于回调,因此不需要多个线程。从开发角度来看,这种模型明显劣于其他模型,但可以在仅提供线程池的平台上使用它。 - user1804599

4

2

Scala使用底层的Java线程实现,使用本地线程

对于Erlang我无法评论。


嗨,戴夫, 我知道最新的JVM只使用本地线程,但是Scala仅使用本地线程存在可扩展性问题。因此,我阅读的一些文章称,一个线程池(工作线程)被用于Scala“并发环境”,而且想法是尽可能少地使用Java线程(本地线程)。 - CHAPa
之前Akka(基于Scala的演员库)使用HawtDispatch(http://hawtdispatch.fusesource.org/)。但是在此期间,他们已经改用其他东西了。我不知道是什么。如果您有兴趣,可以在Akka论坛(akka.io)上向他们询问。 - OlliP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接