“绿色线程”和Erlang的流程之间有什么区别?

时间:2009-12-22 15:43:45

标签: multithreading erlang green-threads lightweight-processes

在阅读了Erlang的轻量级过程后,我非常确定它们是“绿色线程”。直到我读到绿色线程和Erlang的进程之间存在差异。但是我没理解。

实际差异是什么?

3 个答案:

答案 0 :(得分:11)

绿色线程可以直接在它们之间共享数据内存(当然需要同步)。

Erlang不使用“绿色线程”,而是更接近“绿色进程”:进程不直接共享数据内存,而是通过“复制”它(即拥有源数据的独立副本)来实现。

答案 1 :(得分:9)

这种简化太过于说Erlang进程无法直接共享数据内存,并且只能在彼此之间复制值。这更多地描述了如何实现它,以及如何假装它被实现。至少出于性能问题以外的所有目的。

Erlang对作为程序员可以做的事情强制执行一些语义限制。例如,值是不可变的,这意味着在构造之后您无法更改它们。然后人们意识到,多个Erlang进程在内存中访问相同的值是完全正常的,因为无论如何都不能改变它。然后锁是不必要的。

在Erlang / OTP中完成此操作的值得注意的情况是:

  • 在特殊的二进制堆中引用大二进制文件(超过64个字节),并在发送消息时传递对此堆的引用。
  • 文字值放在一个特殊的内存区域,所有引用它们的进程都是指同一内存区域中的值(但是一旦在消息中发送了值,就会在接收过程中重复一次)。
  • 每个节点作为全局原子表,并且原子值实际上是对此表的引用,这使得原子相等测试非常有效(比较指针而不是字符串)。
  • 实验erl -hybrid设置,它结合了进程堆和共享堆,使进程在消息中使用时首先将进程堆中的值复制到共享堆中。我找到了这个thread about hybrid heaps,这也解释了这个概念的一些问题。

可以做的另一个技巧是实际改变值,但要确保它不可见。这是为了进一步解释不可变值是语义限制。

这些是OTP / Erlang实际上会改变值的一些例子:

  • “最近”(R12)处理二进制语法时的优化允许您附加到二进制文件的末尾,实际上不会构造一个添加了新尾部的完整新二进制文件。
  • 有人说,具有直接set_element的新构造的元组可以或曾经被编译器翻译,以实际为元组就地更改元素。

这些优化属于理论,“如果一棵树落在森林里,没有人在那里听到它,它真的发出声音吗?”。也就是说,引用不得转义到要变异的对象。因为那时可以观察到它已经改变了。

这实际上是Erlang语义的意义所在,事情不应该像其他进程正在做的那样产生副作用。我们称之为共享状态,我们根本不喜欢它。

另一个过于简单的简化就是说Erlang没有副作用。但如果有人提出这个问题,那就是另一个问题。

答案 2 :(得分:6)

当人们反对调用Erlang的进程“绿色线程”时,他们并不反对“绿色”部分,他们反对“线程”部分。

线程和进程之间的区别基本上是,线程只有 它们自己的指令指针,但是共享其他所有内容(特别是状态,内存,地址空间)。过程OTOH是完全孤立的,没有任何共享。

Erlang的进程没有任何共享,因此,它们是真正的进程。但是,它们通常以“绿色”方式实施。因此,从技术上讲,它们是“绿色过程”。

当我想强调轻量级实现时,我通常将它们称为“绿色线程”,当我想强调无共享语义。这样我就不必解释“绿色过程”的含义了。