Erlang进程使用消息的顺序是什么?

Erlang进程使用消息的顺序是什么?,erlang,Erlang,消息是按先到先得的方式处理的,还是按时间戳或类似的方式排序的 邮箱始终按照邮件到达的顺序保存 但是,消息的使用顺序由代码决定 如果您有一个普通流程,其中包含一个通用的receive子句,可以接收任何内容,那么您获取消息的顺序与它们到达的顺序相同 loop() -> receive Any -> do_something(Any), loop() end. 但是,如果您有带match子句的选择性receive

消息是按先到先得的方式处理的,还是按时间戳或类似的方式排序的

邮箱始终按照邮件到达的顺序保存

但是,消息的使用顺序由代码决定

如果您有一个普通流程,其中包含一个通用的
receive
子句,可以接收任何内容,那么您获取消息的顺序与它们到达的顺序相同

loop() ->
   receive
        Any ->
            do_something(Any),
            loop()
   end.
但是,如果您有带match子句的选择性
receive
,它将在邮箱中搜索此特定类型的邮件,并使用第一条匹配的邮件,从而有效地跳过不匹配的邮件。在下面的示例中,如果队列中有标记为重要的消息,则将在处理任何其他消息之前处理这些消息。注意:这样的匹配将搜索队列中的所有消息,这对于许多消息来说是个问题。这方面有一些进展,但我还没有跟上

loop() ->
    receive
        {important, Stuff} ->
            do_something_important(Stuff),
            loop();
        Any ->
            do_something(Any)
            loop()
     end.

消息的顺序在一个进程和另一个进程之间保持不变。阅读下列文件:

10.9是否保证信息接收的顺序

是的,但只在一个过程中

如果有一个活动进程,您将向其发送一条消息,然后发送一条消息 B、 可以保证,如果消息B到达,消息A在之前到达 它

另一方面,想象进程p、Q和R。p向A发送消息 Q、 然后是消息B到R。不能保证A到达 在B之前,如果这样的话,分布式Erlang将经历一段相当艰难的时间 是必需的!)

@knutin关于如何在流程中使用消息的观点是正确的。另外,请注意,您可能会使用两个后续的receive语句来确保某条消息在另一条消息之后被使用:

receive
  first ->
    do_first()
end,
receive
  second ->
    do_second()
end

receive语句被阻塞。这将确保您在
do_first()
之前不会
do_second()
。与@knutin的第二种解决方案不同的是,在这种情况下,如果不重要的消息刚好在重要的消息之前到达,则将重要的消息排队。

为了进一步定义答案,我想指出一个事实,如上所述,不匹配模式的消息将被跳过,但在现实中,它们只是简单地放在一边,然后按顺序重新引入(以便首先在不匹配的消息之后到达任何其他消息),以便进行下一个接收模式匹配

例如,当您有一个gen_服务器行为模块时,这个问题实际上表现得最糟糕,因为在这种情况下,始终使用相同的模式匹配调用方案,不在范围内的消息将充斥消息队列,除非您定义一个(丑陋且容易出错的,IMHO)匹配所有模式,如:

receive
    ... -> ...;
    ... -> ...;
    MatchAllPatterns -> ok.
end

注意,处理顺序是(在伪代码中)
foreach消息{foreach模式{如果它匹配…}
。在最后一个代码段中,如果邮箱中存在与
{important,…}
不匹配的早期邮件,则会在收到任何重要邮件之前收到该邮件。也见此