erlang msg selective receive

来源:互联网 发布:那里有淘宝号买 编辑:程序博客网 时间:2024/06/06 07:44
在erlang的一个进程中,如果消息队列里面积压了太多消息,每次做receive的时候就会遍历整个消息队列,对于有大量消息挤压的进程来说很危险。(当然有大量消息挤压说明程序也做的很不好)今天拜读了坚强2002关于make_ref和selective receive的帖子,附地址:http://www.cnblogs.com/me-sa/archive/2013/03/06/make_ref.html

erlang:make_ref()就能够实现skip message received,然后实现receive message的复杂度为O(1).

具体怎么怎么实现的呢?
先看一段代码


erlang:monitor同erlang:make_ref一样,都返回一个ref。再用这个ref在下面的receive进行匹配。

实际上这段代码做了这样一个事情,如下:


在14A的版本中就多了一个recv_mark和recv_set指令,recv_mark指令在make_ref的时候保存了消息队列当前的位置和SomeUniqInteger,在receive的时候,recv_set指令查找进程上下文信息是否存在SomeUniqInteger,如果存在,则把当前指向队列的指针真想recv_mark保存的位置。这样就做到了快速定位。其实就是类似一个索引定位,更通俗来讲就是书签标记。

在gen:call中也大量用到了ref,降低receive message复杂度:



更详细的解释可以参考https://github.com/blackberry/Erlang-OTP/blob/master/lib/compiler/src/beam_receive.erl。


原创粉丝点击