Multithreading 从技术上讲,为什么Erlang中的进程比OS线程更高效? 二郎特征

Multithreading 从技术上讲,为什么Erlang中的进程比OS线程更高效? 二郎特征,multithreading,erlang,Multithreading,Erlang,自2009年起: Erlang并发是快速且可扩展的。它的进程是轻量级的,因为Erlang虚拟机不会为每个创建的进程创建OS线程。它们在VM中创建、调度和处理,独立于底层操作系统。因此,进程创建时间为微秒量级,与并发存在的进程数无关。将此与Java和C#进行比较,在Java和C#中,每个进程都会创建一个底层OS线程:您将得到一些非常有竞争力的比较,Erlang的性能大大优于这两种语言 自2003年起: 我们观察到,创建Erlang进程所需的时间为常数1µs,最多2500个进程;此后,它增加到大约3

自2009年起:

Erlang并发是快速且可扩展的。它的进程是轻量级的,因为Erlang虚拟机不会为每个创建的进程创建OS线程。它们在VM中创建、调度和处理,独立于底层操作系统。因此,进程创建时间为微秒量级,与并发存在的进程数无关。将此与Java和C#进行比较,在Java和C#中,每个进程都会创建一个底层OS线程:您将得到一些非常有竞争力的比较,Erlang的性能大大优于这两种语言

自2003年起:

我们观察到,创建Erlang进程所需的时间为常数1µs,最多2500个进程;此后,它增加到大约3µs,用于多达30000个过程。图的顶部显示了Java和C#的性能。对于少量进程,创建一个进程大约需要300µs。创建超过两千个流程是不可能的

我们看到,对于多达30000个进程,在两个Erlang进程之间发送消息的时间约为0.8µs。对于C#,每条消息大约需要50µs,最多需要1800个进程。Java甚至更糟糕,对于多达100个进程,每条消息大约需要50µs,之后,当有大约1000个Java进程时,每条消息需要10毫秒

我的想法 我在技术上不完全理解为什么Erlang进程在生成新进程方面效率如此之高,并且每个进程的内存占用要小得多。OS和Erlang VM都必须执行调度、上下文切换和跟踪寄存器中的值等等

为什么操作系统线程的实现方式与Erlang中的进程不同?他们需要支持更多的东西吗?为什么它们需要更大的内存占用?为什么它们产卵和通讯速度较慢

从技术上讲,为什么Erlang中的进程在生成和通信方面比OS线程更高效?为什么操作系统中的线程不能以同样有效的方式实现和管理?为什么操作系统线程有更大的内存占用,加上较慢的生成和通信

更多阅读
  • (2008年)
  • (2004年)
  • (1998年)

  • 因为Erlang解释器只需要担心它自己,所以操作系统还有很多其他的事情要担心。

    Erlang进程(大约)与其他语言对应;进程之间没有操作系统强制的分离。(可能会有语言强制的分离,但尽管Erlang做得比大多数都好,但这是一种较低的保护。)因为它们的重量要轻得多,所以可以更广泛地使用

    另一方面,OS线程可以简单地调度到不同的CPU核上,并且(大部分)能够支持独立的CPU处理。操作系统进程类似于操作系统线程,但具有更强的操作系统强制分离。这些功能的代价是操作系统线程和(甚至更多)进程更昂贵


    另一种理解差异的方法是这样的。假设您要在JVM之上编写一个Erlang实现(这不是一个特别疯狂的建议),那么您将使每个Erlang进程成为一个具有某种状态的对象。然后,您将拥有一个线程实例池(通常根据主机系统中的内核数量来确定大小;顺便说一句,这是实际Erlang运行时中的一个可调参数),用于运行Erlang进程。反过来,这将把要完成的工作分配到实际可用的系统资源中。这是一种非常简洁的方式,但完全依赖于每个单独的Erlang进程并没有做很多事情这一事实。当然没关系;Erlang的结构不要求这些单独的进程是重量级的,因为执行程序的是它们的整体集成


    在许多方面,真正的问题是术语。Erlang调用进程(并且对应于CSP、CCS中的同一概念,特别是π演算)的东西与C继承的语言(包括C++、爪哇、C等许多)调用进程或线程的情况完全不同。有一些相似之处(都涉及到一些并发执行的概念),但绝对没有等价性。所以当有人对你说“过程”时要小心;他们可能会理解它意味着完全不同的东西…

    有几个因素:

  • Erlang进程不是操作系统进程。它们由erlangvm使用轻量级协作线程模型(在Erlang级别抢占,但在协作调度的运行时的控制下)实现。这意味着切换上下文要便宜得多,因为它们只在已知的受控点进行切换,因此不必保存整个CPU状态(正常、SSE和FPU寄存器、地址空间映射等)
  • Erlang进程使用动态分配的堆栈,这些堆栈开始时非常小,并根据需要增长。这允许在不占用所有可用RAM的情况下生成数千个甚至数百万个Erlang进程
  • Erlang过去是单线程的,这意味着不需要确保进程之间的线程安全。它现在支持SMP,但同一调度器/核心上的Erlang进程之间的交互仍然非常轻量级(每个核心都有单独的运行队列)

  • 经过进一步研究,我发现了乔·阿姆斯特朗的一篇演讲

    开始(13分钟时):

    [Erlang]是一种并发语言——我的意思是线程是编程语言的一部分,它们不属于操作系统。这就是java语言和C++语言的错误所在。程序中没有线程