Erlang:优先级接收

Erlang:优先级接收,erlang,priority-queue,Erlang,Priority Queue,Erlang中的优先级接收可以按如下方式轻松实现: prio() -> receive {priority, X} -> X after 0 -> receive X -> X end end. 我正在读一篇名为Nyström的论文,其中他们描述了以下问题: 上面的[代码]示例的主要问题是,我们没有考虑到当从内部阻塞接收恢复评估时,邮箱中可能有多条消息。在最坏的情况下,除了第一个元素之外,所有的元素都可能是优

Erlang中的优先级接收可以按如下方式轻松实现:

prio() -> 
  receive 
    {priority, X} -> X 
  after 0 -> 
    receive 
      X -> X 
    end 
  end.
我正在读一篇名为Nyström的论文,其中他们描述了以下问题:

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

我不完全明白

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


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

Erlang是一种完全并发的语言,没有理由不能同时向您发送多条消息。按照“哦,这太快了——其他线程不太可能在这么短的时间内发生冲突”的思路进行假设,本质上与闭上眼睛说“没有种族条件,没有种族条件……”是一样的:这一假设是否成立取决于你的具体情况。例如,所有其他进程在向您发送消息之前可能一直在等待某些事情发生


关于(2):事实上,在我看来,最坏的情况是没有优先级消息,因为每次都必须遍历邮箱:“有优先级消息进来了吗?”

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

考虑到这听起来像是内部接收器将阻塞,直到它接收到匹配的消息。因此,在等待非优先级消息时,您实际上可能会堆积优先级消息,而这与您想要的相反

摆脱这种困境的方法也就是在内部接收上加入一个新的after子句。或者在内部接收器中始终匹配


尽管从功能上看,内部子句应该总是匹配的,但我猜这就是他们所说的。

您突出显示的语句只是说,如果您在阻塞内部接收块中,您可以在处理高优先级消息之前处理低优先级消息(因为您正在匹配所有内容)这不一定是目的


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

别忘了单击Ruby拖鞋。