Multithreading Erlang进程如何映射到内核线程?

Multithreading Erlang进程如何映射到内核线程?,multithreading,erlang,parallel-processing,lightweight-processes,Multithreading,Erlang,Parallel Processing,Lightweight Processes,Erlang以能够支持许多轻量级进程而闻名;它可以做到这一点,因为它们不是传统意义上的进程,甚至不像P线程那样是线程,而是完全在用户空间中的线程 这是很好的(事实上非常棒)。但是,如何在多核/多处理器环境中并行执行Erlang线程呢?当然,它们必须以某种方式映射到内核线程,以便在不同的内核上执行 假设是这样,这是怎么做到的?许多轻量级进程是否映射到单个内核线程 或者有其他方法解决这个问题吗?我在这里只是猜测,但我可以想象有少量线程,它们从公共进程池中选择进程来执行。一旦一个进程碰到一个阻塞操作,

Erlang以能够支持许多轻量级进程而闻名;它可以做到这一点,因为它们不是传统意义上的进程,甚至不像P线程那样是线程,而是完全在用户空间中的线程

这是很好的(事实上非常棒)。但是,如何在多核/多处理器环境中并行执行Erlang线程呢?当然,它们必须以某种方式映射到内核线程,以便在不同的内核上执行

假设是这样,这是怎么做到的?许多轻量级进程是否映射到单个内核线程


或者有其他方法解决这个问题吗?

我在这里只是猜测,但我可以想象有少量线程,它们从公共进程池中选择进程来执行。一旦一个进程碰到一个阻塞操作,执行它的线程就会把它放在一边,然后选择另一个。当一个正在执行的进程导致另一个进程解锁时,新解锁的进程将被放入池中。我认为线程也可能会停止进程的执行,即使它在某些点没有被阻塞以服务于其他进程。

答案取决于使用的VM:

1) 非SMP:有一个调度程序(OS线程),它执行所有Erlang进程,这些进程取自可运行进程池(即未被阻止的进程,例如,
接收

2) SMP:有K个调度程序(OS线程,K通常是多个CPU核),它从共享进程队列执行Erlang进程。它是一个简单的FIFO队列(带有锁以允许多个OS线程同时访问)

3) R13B和更新版本中的SMP:将有K个调度程序(与以前一样),从多个进程队列执行Erlang进程。每个调度程序都有自己的队列,因此将添加从一个调度程序到另一个调度程序的进程迁移逻辑。此解决方案将通过避免共享进程队列中的过度锁定来提高性能


有关更多信息,请参阅爱立信公司Kenneth Lundin为2008年11月13日在斯德哥尔摩举行的Erlang用户会议所做的准备。

我想补充前面的答案

Erlang,或者更确切地说是Erlang运行时系统(erts),将调度程序(OS线程)的数量和运行队列的数量默认为平台上处理元素的数量。即处理器内核或硬件线程。您可以在运行时使用以下命令更改这些设置:

erlang:system_flag(schedulers_online, NP) -> PrevNP
Erlang进程与任何调度器都没有任何关联。平衡调度程序之间进程的逻辑遵循两条规则。1) 饥饿的调度程序将从另一个调度程序窃取工作。2) 迁移路径设置为将进程从具有大量进程的调度程序推送到工作量较少的调度程序。这样做是为了确保每个进程的减少计数(执行时间)的公平性

但是,调度程序可以锁定到特定的处理元素。默认情况下不会执行此操作。要让ERT执行调度程序->核心关联,请使用:

erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind

文档中还可以找到其他几种绑定类型。在重载情况下,使用关联可以极大地提高性能!尤其是在高锁争用情况下。此外,linux内核至少不能处理超线程。如果您的平台上有超线程,那么您应该在erlang中真正使用此功能。

我想为已接受的答案中描述的内容添加一些输入

Erlang调度器是Erlang运行时系统的重要组成部分,它提供了操作系统线程上轻量级进程概念的抽象和实现

每个调度程序在单个OS线程中运行。通常,硬件上的调度程序的数量与CPU(核心)的数量相同(但它是可配置的,当调度程序的数量超过硬件核心的数量时,自然不会带来太多价值)。系统还可能配置为调度器不会在操作系统线程之间跳转

现在,在创建Erlang进程时,ERT和调度器完全负责管理生命周期、资源消耗以及内存占用等

核心实现细节之一是,当调度器从运行队列中选取该进程时,每个进程都有2000个可用的时间预算缩减。系统中的每个进度(甚至I/O)都保证有一个预算。这就是为什么ERTS实际上是一个具有先发制人多任务处理的系统

我推荐杰斯珀·路易斯·安徒生写的一篇关于这个话题的博文

简而言之:Erlang进程不是操作系统线程,也不会直接映射到它们。Erlang调度器运行在操作系统线程上,提供更细粒度Erlang进程的智能实现,将这些细节隐藏在程序员的眼睛后面