邮件是以先到先得的方式处理还是按时间戳或类似的方式排序?
答案 0 :(得分:12)
在进程和另一个进程之间保留消息顺序。阅读FAQ:
10.9是否保证了信息接收的顺序?
是的,但只在一个过程中。
如果有实时进程,则发送消息A然后发送消息 B,保证如果消息B到达,则消息A到达之前 它
另一方面,假设进程P,Q和R.P发送消息A. Q,然后消息B到R.不能保证A到达 在B之前。(如果这样,分布式Erlang将会非常艰难 是必需的!)
@knutin关于如何在流程中使用消息是正确的。另外,请注意您可以使用两个后续接收语句来确保在之后消耗某个消息:
receive
first ->
do_first()
end,
receive
second ->
do_second()
end
接收声明正在阻止。这样可以确保您do_second()
之前永远不会do_first()
。与@kututin的第二个解决方案的不同之处在于,在这种情况下,如果某个不重要的东西在重要之前到达,则将重要位置排队。
答案 1 :(得分:4)
邮箱始终按邮件到达的顺序保存。
但是,消息的消费顺序取决于您的代码。
如果您的普通receive
子句有一个接收任何内容的普通进程,则获取消息的顺序与它们到达的顺序相同。
loop() ->
receive
Any ->
do_something(Any),
loop()
end.
但是,如果您有一个带有匹配子句的选择性receive
,它将在邮箱中搜索此特定类型的邮件并使用第一个匹配的邮件,从而有效地跳过不匹配的邮件。在以下示例中,如果队列中标记为重要的消息,则将在任何其他消息之前处理它们。注意:这样的匹配将搜索队列中的所有消息,这对许多消息都是一个问题。这个领域有一些发展,但我没有达到速度。
loop() ->
receive
{important, Stuff} ->
do_something_important(Stuff),
loop();
Any ->
do_something(Any)
loop()
end.
答案 2 :(得分:1)
为了进一步定义答案,我想指出这样一个事实:如上所述,没有模式匹配的消息被跳过,但实际上它们被简单地放在一边然后按顺序重新引入(所以首先是用于下一次接收模式匹配的其他消息(在不匹配的消息之后到达)。
当你有一个gen_server行为模块时,这个问题确实表现得最糟糕,因为在这种情况下,总是有相同的模式匹配调用方案,不在范围内的消息将泛滥消息队列,除非你定义一个(丑陋的)并且容易出错,恕我直言)匹配所有模式如:
receive
... -> ...;
... -> ...;
MatchAllPatterns -> ok.
end