Erlang:优先接收

izkcnapc  于 2022-12-08  发布在  Erlang
关注(0)|答案(4)|浏览(147)

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

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

我正在阅读一篇名为Priority Messaging made Easy的论文,作者是Nyström,他们在文中描述了以下问题:
上面的[code]示例的主要问题是,我们没有考虑到,当从内部阻塞接收恢复求值时,邮箱中可能有多个消息。在最坏的情况下,可能有大量元素,除了第一个元素之外,所有元素都可能是优先级消息。在这种情况下,我们实际上完成了与我们打算做的完全相反的事情。
我不太明白。
问题(一):我假设一旦有一条***消息到达消息队列,内部阻塞接收就会被“调用”(即恢复),对吗?假设在从内部阻塞接收恢复所需的短时间内,队列中已经有一大堆消息在等待,这现实吗?
问题(二):此外,最坏的情况是一个队列中有一条普通消息和许多优先级消息。由于所有的receive子句都首先针对队列中的第一条消息进行检查,然后针对队列中的第二条消息进行检查,......(来源:这book,第69-70页)不应该是:队列末尾有一个优先级消息的许多普通消息?

jvlzgdj9

jvlzgdj91#

Erlang是一种完全并发的语言,没有理由不能在同一时间发送多个消息。假设“哦,这太快了--在这么短的时间内,其他线程不太可能做冲突的事情”,这基本上就等于闭上眼睛说“没有竞态条件这回事,根本就没有什么种族条件......”

oxiaedzo

oxiaedzo2#

On (1): Whether this assumption can be made depends on details of your situation. For example, all other processes may have been waiting for something to happen before sending you their messages.
On (2): In fact, it seems to me that the worst case would be no priority messages, as the mailbox would have to be traversed every time: "Has a priority message come in yet?"

qkf9rpyu

qkf9rpyu3#

According to the erlang reference manual receive traverses the mailbox in time order. and blocks till a message matches the one of the clauses.
Given that it sounds like the inner recieve is going to block till it recieves a matching message. Because of this you might actually stack up priority messages while waiting for non-priority messages which is the opposite of what you want.
Too ways out of this predicament are throwing a new after clause on the inner receive. Or always match in the inner recieve.
Although looking at their function the inner clause should always match but I'm guessing this is what they were talking about.

wydwbb8l

wydwbb8l4#

您突出显示的语句只是说,如果您在阻塞内部接收块中,则可以在处理高优先级消息之前处理低优先级消息(因为您要匹配所有内容),这不一定是意图。
这是一种边缘情况--我发现,当您需要某种类型的过滤时,高效地处理消息是很重要的。在其他情况下,我还监视了进程队列深度,并相应地改变了策略。作为后者的一个示例,一个简单的日志记录gen_server类型进程(它使用cast发送日志消息)可能会相当麻烦,因为将日志消息写入磁盘比将消息推送到进程要慢得多。如果队列深度太大,我会丢弃通常记录的信息/垃圾邮件类型的消息,只处理(写入磁盘)关键的消息。

相关问题