在阅读了Erlang的轻量级过程后,我非常确定它们是“绿色线程”。直到我读到绿色线程和Erlang的进程之间存在差异。但是我没理解。
实际差异是什么?
答案 0 :(得分:11)
绿色线程可以直接在它们之间共享数据内存(当然需要同步)。
Erlang不使用“绿色线程”,而是更接近“绿色进程”:进程不直接共享数据内存,而是通过“复制”它(即拥有源数据的独立副本)来实现。
答案 1 :(得分:9)
这种简化太过于说Erlang进程无法直接共享数据内存,并且只能在彼此之间复制值。这更多地描述了如何实现它,以及如何假装它被实现。至少出于性能问题以外的所有目的。
Erlang对作为程序员可以做的事情强制执行一些语义限制。例如,值是不可变的,这意味着在构造之后您无法更改它们。然后人们意识到,多个Erlang进程在内存中访问相同的值是完全正常的,因为无论如何都不能改变它。然后锁是不必要的。
在Erlang / OTP中完成此操作的值得注意的情况是:
erl -hybrid
设置,它结合了进程堆和共享堆,使进程在消息中使用时首先将进程堆中的值复制到共享堆中。我找到了这个thread about hybrid heaps,这也解释了这个概念的一些问题。可以做的另一个技巧是实际改变值,但要确保它不可见。这是为了进一步解释不可变值是语义限制。
这些是OTP / Erlang实际上会改变值的一些例子:
这些优化属于理论,“如果一棵树落在森林里,没有人在那里听到它,它真的发出声音吗?”。也就是说,引用不得转义到要变异的对象。因为那时可以观察到它已经改变了。
这实际上是Erlang语义的意义所在,事情不应该像其他进程正在做的那样产生副作用。我们称之为共享状态,我们根本不喜欢它。
另一个过于简单的简化就是说Erlang没有副作用。但如果有人提出这个问题,那就是另一个问题。
答案 2 :(得分:6)
当人们反对调用Erlang的进程“绿色线程”时,他们并不反对“绿色”部分,他们反对“线程”部分。
线程和进程之间的区别基本上是,线程只有 它们自己的指令指针,但是共享其他所有内容(特别是状态,内存,地址空间)。过程OTOH是完全孤立的,没有任何共享。
Erlang的进程没有任何共享,因此,它们是真正的进程。但是,它们通常以“绿色”方式实施。因此,从技术上讲,它们是“绿色过程”。
当我想强调轻量级实现时,我通常将它们称为“绿色线程”,当我想强调无共享语义。这样我就不必解释“绿色过程”的含义了。