Erlang使用消息传递来在进程之间进行通信。它如何处理并发传入消息?使用什么数据结构?
答案 0 :(得分:2)
流程收件箱由2个列表组成。
主要的是 fifo ,其中存储了所有传入的消息,等待进程按照接收的确切顺序检查它们。第二个是堆栈,用于存储与给定接收语句中的任何子句不匹配的消息。
当进程执行receive语句时,它将尝试"模式匹配"在第一次匹配发生之前,按照它们被声明的顺序对接收的每个子句的第一条消息。
如果未找到匹配项,则将消息从fifo中删除并堆叠在第二个列表上,然后该过程将使用下一条消息进行迭代(请注意,流程执行可能会在同一时间暂停,因为fifo是空的,或者因为它已达到他的减少额度")
如果找到匹配项,则会从fifo中删除该邮件,并按照原始顺序在fifo中恢复堆叠邮件
请注意,模式匹配过程包括过程变量中任何有趣内容的副本,例如{request,write,Value,_} -> ...
成功,这意味着被检查的消息是一个4元素元组,其第一个和第二个元素分别是原子request
和write
,其第三个元素与变量Value成功模式匹配:这意味着如果以前未绑定,或者该值与元素匹配,则Value绑定到此元素,最后,第四个元素被丢弃。完成此操作后,无需检索原始消息
答案 1 :(得分:1)
您可以通过查看erl_message原语erl_message.c及其声明文件erl_message.h来获取一些信息。
您可能还会发现这些主题很有用(one,two),但我认为您的问题更多的是关于正在使用的数据结构。
ERTS结构
erlang运行时系统(erts)为消息传递的调度(see source)分配分段(链接)堆。可以找到ErlHeapFragment结构here。
但是,每个进程还有一个非常简单的fifo队列结构,它们从堆中复制消息以使用它们。队列的基础是链表,并且存在绕过堆并直接使用进程队列的机制。有关该人的更多信息,请参阅here。
最后,每个流程还有一个堆栈(也作为列表实现),其中放置了 receive 中没有匹配模式的消息。这可以作为存储可能很重要的消息的一种方式,但是在收到另一个不同的消息之前,该进程无法处理(匹配)。这是erlang如何拥有如此强大的热交换功能的一部分。机制。
并发消息传递语义
在较高级别,erts接收消息并将其放入堆中(除非明确告知不要),并且每个进程负责选择要复制到其自己的进程队列中的消息。从我读过的内容来看,队列中当前的消息将在再次从堆中复制之前被处理,但可能会有更多的细微差别。