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

Dan*_*ski 11 erlang multithreading lightweight-processes green-threads

在阅读了Erlang的轻量级过程后,我非常确定它们是"绿色线程".直到我读到绿色线程和Erlang的进程之间存在差异.但我不明白.

有什么实际差异?

jld*_*ont 12

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

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


Chr*_*ian 9

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

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

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

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

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

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

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

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

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

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


Jör*_*tag 6

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

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

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

当我想强调轻量级实现时,我通常将它们称为"绿色线程",当我想强调无共享语义时,我称之为"进程" .这样我就无需用"绿色过程"来解释我的意思.