Elixir/Erlang可以复制一个进程,包括它的内存吗?

Nat*_*ong 6 erlang process elixir

我正在考虑使用Elixir解决问题,主要是因为能够廉价地产生大量进程.

在我的场景中,我想创建几个"原始"进程,将特定的,不可变数据加载到内存中,然后根据需要复制这些进程.副本都将使用相同的基础数据,但使用它执行不同的只读任务; 例如,想象一个"原始"在记忆中具有"战争与和平"的文本,并且该原始的每个副本对文本进行不同类型的分析.

我的问题:

  • 是否可以复制Elixir/Erlang VM中的现有进程,内存内容等?
  • 如果是这样,每个副本是否会消耗与原始内存一样多的内存,或者它们可以共享内存,因为Unix进程使用"copy on write"策略?(在这种情况下,不会有后续写入.)

rvi*_*ing 6

没有内置的方法来复制进程.最简单的方法是启动"原始"过程和"副本",并将消息中的所有相关数据发送到副本.进程不共享数据,因此没有更有效的方法.将数据放在ETS表中仅部分有助于共享,因为ETS表中的数据在使用时会复制到进程中,但是,您不需要在进程堆中包含所有数据.


leg*_*cia 5

Erlang进程除了存储在变量(和进程字典)中之外没有特定于进程的数据,因此要创建进程内存的副本,只需生成一个新进程,将所有相关变量作为参数传递给函数.

通常,进程之间不共享内存; 一切都被复制了.例外情况是ETS表(尽管数据是在进程读取时从ETS表复制的),以及大于64字节的二进制文件.如果您将"War and Peace"存储在二进制文件中,并将其发送到每个工作进程(或在您生成这些工作进程时传递它),那么进程将共享内存,只有在他们想要修改二进制文件时才复制它.有关详细信息,请参阅Erlang效率指南中有关二进制文件章节.

  • 我将从[ETS表]开始(http://www.erlang.org/doc/man/ets.html).当您从ETS表中读取数据时,将复制数据,如果您只是同时查看其中的一部分,则工作进程应该能够跟上垃圾回收. (2认同)
  • 我也会使用ETS,或者只是根据需要将相关数据发送到其他流程.但是,如果您进行基准测试并确实存在性能问题,则可以将键值编码为大型二进制文件,并让每个进程从中提取信息.IIRC,Kresten在他的HanoiDB应用程序中使用了这种技术:https://github.com/krestenkrab/hanoidb (2认同)
  • 使用ETS表的麻烦在于每个进程都没有自己的数据副本.同样使用ETS意味着每次访问数据时都会不断地将数据复制到进程或从进程复制数据.当然,这取决于您希望这些副本如何工作. (2认同)