【发布时间】:2011-02-12 01:49:36
【问题描述】:
Erlang 的特点
来自Erlang Programming (2009):
Erlang 并发是快速且可扩展的。它的进程是轻量级的,因为 Erlang 虚拟机不会为每个创建的进程创建一个 OS 线程。它们在 VM 中创建、调度和处理,独立于底层操作系统。因此,进程创建时间是微秒级的,并且与同时存在的进程数无关。将此与 Java 和 C# 进行比较,后者为每个进程创建一个底层操作系统线程:您将获得一些非常有竞争力的比较,Erlang 大大优于这两种语言。
来自 Concurrency oriented programming in Erlang (pdf)(slides)(2003):
我们观察到创建一个 Erlang 进程所花费的时间是恒定的 1µs 到 2,500 个进程;此后,对于多达 30,000 个过程,它增加到大约 3µs。 Java 和 C# 的性能显示在图的顶部。对于少量进程,创建一个进程大约需要 300µs。创建超过两千个进程是不可能的。
我们看到,对于多达 30,000 个进程,两个 Erlang 进程之间发送消息的时间约为 0.8µs。对于 C#,每条消息大约需要 50µs,直到最大进程数(大约 1800 个进程)。 Java 更糟糕的是,对于多达 100 个进程,每条消息大约需要 50µs,此后当有大约 1000 个 Java 进程时,它迅速增加到每条消息 10ms。
我的想法
从技术上讲,我不完全理解为什么 Erlang 进程在生成新进程方面如此高效,并且每个进程的内存占用要小得多。操作系统和 Erlang 虚拟机都必须进行调度、上下文切换以及跟踪寄存器中的值等等......
为什么操作系统线程的实现方式与 Erlang 中的进程不同?他们是否必须支持更多的东西?为什么他们需要更大的内存占用?为什么它们的产卵和交流速度较慢?
从技术上讲,为什么 Erlang 中的进程在生成和通信方面比操作系统线程更有效?为什么不能以同样有效的方式实现和管理操作系统中的线程?为什么操作系统线程的内存占用更大,生成和通信更慢?
更多阅读
【问题讨论】:
-
在尝试理解假设为真的原因之前,您需要确定是否该假设为真的——例如,有证据支持。您是否有任何同类比较的参考,证明 Erlang 进程实际上是比(比如说)最新 JVM 上的 Java 线程更有效?还是直接使用操作系统进程和线程支持的 C 应用程序? (后者对我来说似乎非常非常不可能。前者只是有点可能。)我的意思是,在有限的环境(弗朗西斯科的观点)下,这可能是真的,但我想看看数字。
-
@Donal:与许多其他绝对陈述一样。 :-)
-
@Jonas:谢谢,但我知道日期(1998-11-02)和 JVM 版本(1.1.6)并停止了。 Sun 的 JVM 在过去 11.5 年 中得到了相当大的改进(大概 Erlang 的解释器也是如此),尤其是在线程领域。 (为了清楚起见,我并不是说这个假设不正确[弗朗西斯科和多纳尔已经指出了为什么 Erland 可以在那里做某事];我说的是不应该从表面上看未经检查。)
-
@Jonas: "...但我猜你可以在 Erlang 中做到这一点..." 这是“猜测”部分,伙计。 :-) 你猜测 Erlang 的进程切换规模超过了数千。您猜测它比 Java 或 OS 线程做得更好。猜测和软件开发并不是一个很好的组合。 :-) 但我想我已经表达了我的观点。
-
@T.J. Crowder:安装 erlang 并运行
erl +P 1000100 +hms 100,然后输入{_, PIDs} = timer:tc(lists,map,[fun(_)->spawn(fun()->receive stop -> ok end end) end, lists:seq(1,1000000)]).,然后等待大约三分钟得到结果。就是这么简单。在我的笔记本电脑上,每个进程需要 140us 和 1GB 的整个 RAM。不过是直接form shell,编译后的代码应该会更好。
标签: multithreading erlang