如果有的话,Erlang进程如何映射到内核线程?
Erlang以能够支持许多轻量级进程而闻名; 它可以这样做,因为它们不是传统意义上的进程,甚至不像P线程中的线程,而是完全在用户空间中线程化。
这是好的(实际上很棒)。 但是,在多核/多处理器环境中,Erlang线程如何并行执行呢? 当然,他们必须以某种方式映射到内核线程才能在不同的内核上执行?
假设情况如此,这是如何完成的? 很多轻量级进程是否映射到单个内核线程?
还是有另一种解决这个问题的方法?
回答取决于使用的VM:
1) 非SMP :有一个调度程序 (操作系统线程),它执行从可运行进程池 (即那些没有被receive
阻塞的进程)获取的所有Erlang进程,
2) SMP :有K个调度程序 (操作系统线程,K通常是一些CPU核心),它们从共享进程队列中执行Erlang进程。 这是一个简单的FIFO队列(带锁以允许从多个OS线程同时访问)。
3) R13B和更新版本中的SMP :将会有K个调度器 (和以前一样)从多个进程队列中执行Erlang进程。 每个调度程序都有自己的队列,因此将会添加从一个调度程序到另一个调度程序的过程迁移逻辑 。 此解决scheme将通过避免共享进程队列中的过度locking来提高性能。
欲了解更多信息,请参阅本文由爱立信公司的Kenneth Lundin于2008年11月13日在斯德哥尔摩举行的Erlang用户大会上准备。
我想赞扬以前的答案。
Erlang或Erlang运行时系统(erts)会将调度程序(OS线程)的数量以及运行队列的数量默认为平台上处理元素的数量。 这是处理器核心或硬件线程。 您可以使用以下方式在运行时更改这些设
erlang:system_flag(schedulers_online, NP) -> PrevNP
Erlang进程与任何调度器都没有任何关系。 调度程序之间进程的逻辑平衡遵循两条规则。 1)饥饿的调度程序将从另一个调度程序窃取工作。 2)迁移path被设置为将具有大量进程的调度器的进程推送到具有较less工作的调度器。 这样做是为了确保每个过程的减less计数(执行时间)的公平性。
然而,调度程序可以locking到特定的处理元素。 这不是默认的。 要让erts执行计划程序 – >核心关联使用:
erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind
其他几种绑定types可以在文档中find。 使用亲和力可以大大提高重载情况下的性能! 特别是在高锁争用的情况下。 另外,linux内核无法处理超线程。 如果你的平台上有超线程,你应该在erlang中使用这个特性。
我在这里纯粹猜测,但我想象有less量的线程,从一个普通的进程池中挑选进程执行。 一旦一个进程遇到阻塞操作,执行它的线程把它放在一边,select另一个。 当正在执行的进程导致另一个进程被解除阻塞时,新的未被阻止的进程将被放入池中。 我想一个线程也可能会停止执行一个进程,即使它没有被阻塞在某些点来服务其他进程。
我想在接受的答案中join一些内容。
Erlang调度程序是Erlang运行时系统的重要组成部分,它提供了在OS线程上轻量级进程概念的抽象和实现。
每个调度程序在单个操作系统线程中运行。 通常情况下,调度程序与硬件上的CPU(内核)数量一样多(它可以configuration,当调度程序的数量超过硬件内核时,自然不会带来太多价值)。 系统也可能被configuration为调度程序不会在OS线程之间跳转。
现在,在创buildErlang进程时,完全由ERTS和Scheduler负责pipe理生命周期和资源消耗以及内存占用等。
其中一个核心的实现细节是,当调度程序从运行队列中select该进程时,每个进程的时间预算可以减less2000个。 系统中的每个进度(甚至是I / O)都保证有一个减less的预算。 这实际上使得ERTS成为抢先式多任务系统。
我会推荐一个伟大的博客postJesper路易斯安德森http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html
简短的回答:Erlang进程不是OS线程,不直接映射到它们。 Erlang调度程序是在操作系统线程上运行的,它提供了更细致的Erlang进程的智能实现,隐藏了程序员眼中的这些细节。