在 Erlang 中发送消息

Message sending in Erlang under the hood

Erlang 中的消息发送是 异步,这意味着 PidB ! msg 等发送表达式由进程 PidA 计算后立即产生结果 msg 而不会阻止后者。自然地,它的副作用就是发送 msgPidB

由于这种消息传递模式 提供任何消息传递保证,因此发件人必须通过要求收件人进行相应确认来确定消息是否已实际传递。毕竟,可能并不总是需要确认消息是否已送达。

这在本地和分布式情况下都适用:在后一种情况下,发送方不能简单地假设远程节点始终可用;在本地场景中,进程位于同一个 Erlang 节点上,进程可能会向不存在的进程发送消息。


我很好奇 ! 消息发送的副作用部分在发送方和接收方进程处于活动状态时如何在 VM 级别工作在 相同的 节点上。特别是,我想知道发送操作是否在返回之前完成。通过完成,我的意思是说对于本地进程的特定情况,发送方:(i) 获取接收方消息队列的锁,(ii ) 将消息直接写入其队列,(iii) 释放锁,(iv) 最后 returns.

我遇到了这个post,虽然我没有完全理解,但它似乎表明可能是这种情况。

Erik Stenman 的 The Beam Book, which explains many implementation details of the Erlang VM, answers your question in great detail in its "Lock Free Message Passing" 部分。完整的答案太长,无法在此处复制,但对您的问题的简短回答是,是的,发送进程将其消息完全复制到接收方可访问的内存区域。如果你查阅这本书,你会发现它比你在问题中描述的步骤 i-iv 更复杂,因为 send 标志不同,锁是否已经被其他进程占用,多个内存区域,接收进程的状态。