【问题标题】:In what order does an Erlang process consume messages?Erlang 进程以什么顺序消费消息?
【发布时间】:2011-10-14 23:18:12
【问题描述】:

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

【问题讨论】:

    标签: erlang


    【解决方案1】:

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

    当你有一个 gen_server 行为模块时,这个问题确实表现得最糟糕,因为在这种情况下,总是有相同的模式匹配调用方案,除非你定义一个(丑陋并且容易出错,恕我直言)匹配所有模式,例如:

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

    【讨论】:

      【解决方案2】:

      消息的顺序在一个进程和另一个进程之间保留。读自FAQ

      10.9 消息接收顺序是否有保证?

      是的,但仅限于一个进程内。

      如果有一个实时进程并且您向它发送消息 A 然后发送消息 B,保证如果消息B到达,消息A之前到达 它。

      另一方面,想象进程 P、Q 和 R。P 将消息 A 发送到 Q,然后向 R 发送消息 B。不能保证 A 到达 在 B 之前。(如果这样,分布式 Erlang 将会非常艰难 是必需的!)

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

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

      接收语句被阻塞。这将确保您在do_first() 之前永远不会do_second()。与@knutin 的第二个解决方案的不同之处在于,在这种情况下,如果 重要的东西刚好在重要 的东西之前到达,你就将重要的部分排队。

      【讨论】:

        【解决方案3】:

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

        但是,消息的消费顺序由您的代码决定。

        如果您有一个普通的流程,其中包含接收任何内容的通用 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.
        

        【讨论】:

        • 请注意,处理顺序是(在伪代码中)foreach message { foreach pattern { if it matches ...} }。在最后一个代码 sn-p 中,如果邮箱中存在与{important, ...} 不匹配的较早消息,它将在任何重要的事情之前收到。另请参阅stackoverflow.com/questions/12248111/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-15
        • 2014-06-07
        • 2012-04-27
        • 2023-03-31
        • 1970-01-01
        • 2020-02-22
        相关资源
        最近更新 更多