【问题标题】:Erlang: priority receiveErlang:优先接收
【发布时间】:2010-10-31 21:28:09
【问题描述】:

Erlang 中的优先接收可以很容易地实现如下:

prio() -> 
  receive 
    {priority, X} -> X 
  after 0 -> 
    receive 
      X -> X 
    end 
  end.

我正在阅读 Nyström 的一篇名为 Priority Messaging made Easy 的论文,其中描述了以下问题:

[代码]示例[上面]的主要问题是,我们没有考虑到当从内部阻塞接收恢复评估时,邮箱中可能有不止一条消息。在最坏的情况下,除了第一个(可能是大量的)元素之外的所有元素都可能是优先消息。在这种情况下,我们实际上会完成与我们打算做的完全相反的事情。

我不完全明白。

问题 (1):我假设一旦 一个 消息到达消息队列,内部阻塞接收将被“调用”(即恢复),正确的?假设在从内部阻塞接收恢复所需的短时间内,队列中已经有一大堆消息在等待,这是否现实?

问题(2):此外,最坏的情况被描述为一个队列,其中包含一条普通消息和许多优先级消息。由于所有接收子句首先检查队列中的第一条消息,然后检查队列中的第二条消息,...(来源:book,第 69-70 页)不应该是:很多队列末尾有优先级消息的普通消息?

【问题讨论】:

    标签: erlang priority-queue


    【解决方案1】:

    Erlang 是一种完全并发的语言,没有理由不能同时发送多条消息。沿着“哦,这很快——其他线程不太可能在那么短的时间内做一些冲突的事情”这样的假设,本质上与闭上眼睛说“没有竞争条件这样的事情,有没有竞争条件之类的东西......”

    【讨论】:

    • 别忘了点击你的红宝石拖鞋。
    【解决方案2】:

    开(1):是否可以做出这种假设取决于您的具体情况。例如,所有其他进程在向您发送消息之前可能一直在等待某事发生。

    On (2):事实上,在我看来,最坏的情况是 no 优先消息,因为每次都必须遍历邮箱:“有一个优先消息进来还没有?”

    【讨论】:

      【解决方案3】:

      根据erlang参考手册receive按时间顺序遍历邮箱。并阻塞,直到消息与其中一个子句匹配。

      鉴于听起来内部接收会阻塞,直到它收到匹配的消息。因此,您实际上可能会在等待与您想要的相反的非优先级消息时堆叠优先级消息。

      摆脱这种困境的方法是在内部接收上抛出一个新的 after 子句。或者总是在内部接收中匹配。

      虽然从他们的功能来看,内部子句应该总是匹配的,但我猜这就是他们在谈论的内容。

      【讨论】:

        【解决方案4】:

        您强调的声明只是说,如果您处于阻塞内部接收块中,您可以在高优先级消息之前处理低优先级消息(因为您匹配所有内容),这不一定是意图。

        这有点极端——我发现当您需要某种类型的过滤时,高效地处理消息很重要。在其他情况下,我还监控了进程队列深度并相应地改变了我的策略。作为后者的一个示例,一个简单的日志记录 gen_server 类型进程(用于发送日志消息)可能会得到相当备份,因为将日志消息写入磁盘可能比将消息推送到进程慢很多。如果队列深度太大,我会丢弃我通常记录的信息/垃圾邮件类型的消息,只处理(写入磁盘)关键消息。

        【讨论】:

          猜你喜欢
          • 2020-09-11
          • 2010-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-09
          • 2012-03-15
          相关资源
          最近更新 更多