`
litaocheng
  • 浏览: 337161 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

gen_server2 - OTP gen_server优化版(更正)

阅读更多

rabbitmq 的代码中包含一个gen_server2 , 其对Erlang OTP中的gen_server进行了一些优化.


gen_server.erl

loop(Parent, Name, State, Mod, hibernate, Debug) ->
    proc_lib:hibernate(?MODULE,wake_hib,[Parent, Name, State, Mod, Debug]);
loop(Parent, Name, State, Mod, Time, Debug) ->
    Msg = receive
	      Input ->
		    Input
	  after Time ->
		  timeout
	  end,
    decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, false).



gen_server2.erl

loop(Parent, Name, State, Mod, Time, Queue, Debug) ->
    receive
        Input -> loop(Parent, Name, State, Mod,
                      Time, queue:in(Input, Queue), Debug)
    after 0 ->
            case queue:out(Queue) of
                {{value, Msg}, Queue1} ->
                    process_msg(Parent, Name, State, Mod,
                                Time, Queue1, Debug, Msg);
                {empty, Queue1} ->
                    receive
                        Input ->
                            loop(Parent, Name, State, Mod,
                                 Time, queue:in(Input, Queue1), Debug)
                    after Time ->
                            process_msg(Parent, Name, State, Mod,
                                        Time, Queue1, Debug, timeout)
                    end
            end
    end.



gen_server2中在主循环中,使用queue保存msg, 需要处理消息时,首先从queue中取出一个消息进行处理,如果queue为空,则使用receive接受消息, 随后处理,如果指定时间内没有任何消息,则处理timeout消息.

将消息保存在queue中, 减小了process内置msg queue的长度, 当我们需要处理消息时,首先从外部的queue中获取消息, 而不用遍历整个内置的msg queue, 当process的负载很大, 也就是消息队列中消息较多时,使用这种方法性能提升很大. 这里其实采用了一个分治的方法,将一个大的消息队列,切分成2个小的消息队列.

gen_server2中有一个不是很完善的地方,就是没有处理 Mod:init/1 返回{ok, State, hibernate}的情况,这个可以参考gen_server结合sys进行实现.

最后看看两者性能比较, 引用Joe' Bogmerle 所做的测试:


可以看出gen_server2性能有明显提升!


Update: 感谢yufeng的提醒,原谅我的不求甚解.

gen_server2, 其首先从inner msg quue中匹配任意(ANY)一条消息, 随后添加都外部的quue队列中. 随后继续进入Loop循环, 因此, 其实际的做法是首先将所有的消息从inner msg queue中取出,然后放入queue队列, 当inner msg quue没有任何消息时, 也就是after 0 的情况, 然后从queue中取出(queue:out/1)一个消息,交给process_msg进行处理. 如果queue为空,则进行第二次将inner msg导入到quue中的过程.


这样做gen_server2使所有的msg经历了一个从inner msg queue到外部queue的过程, 其减少了虚拟机内部的资源消耗, 但是这些消息都存储到外部的queue, 总体来说内存还是没有什么太大的变化.


最大的不同是:

gen_server2 收到任何一条消息放到外部的queue中, 当inner msg quue为空后,才进行消息处理, 继续循环.

gen_server 收到任何一条消息后,立即进行处理, 处理完成后继续循环.


我没有亲自做测试, 至于上面merle相关的测试, 唯一的解释就是, gen_server2拥有一个比较"空闲"的inner msg queue, 对于其性能提升具有某种好处. 回头我会具体测试一下.


 

分享到:
评论
2 楼 mryufeng 2009-02-11  
选择性消息接收是有这个缺陷的!

http://blog.yufeng.info
1 楼 ShiningRay 2009-02-10  
很好很强大

楼主功力愈加深厚啦

相关推荐

    gen_server tasting 之超简单名称服务(续)

    在IT行业中,`gen_server`是Erlang OTP(开放电信平台)框架中的一个核心组件,它提供了一种模式化的方式来实现服务器进程。本篇博客“gen_server tasting 之超简单名称服务(续)”主要探讨了如何使用gen_server来...

    otp_src_R11B-5.tar.gz_OTP_erlang_otp-src-R11B_otp_s

    "otp_src"意味着这个压缩包包含了编译和构建OTP所需的所有源代码,而"otp_s"可能指的是这个版本的源代码版或特定的构建设置。 要使用这个压缩包,你需要首先解压,然后配置并编译源代码。通常,这会涉及到运行配置...

    otp-OTP-20.0.tar.gz

    在这个场景中,"otp-OTP-20.0.tar.gz"可以在CentOS上运行,意味着OTP 20.0与这个Linux发行版是兼容的,可以用于构建和运行Erlang应用程序,包括RabbitMQ 3.7.0。 在Erlang OTP框架中,有几个关键组件值得关注: 1....

    基于Erlang的gen_tcp聊天室代码,功能完整

    gen_tcp是Erlang OTP(开放电信平台)提供的一种行为模块,它允许程序员以面向过程的方式处理TCP连接。gen_tcp提供了创建、监听、接受和关闭TCP套接字的函数,以及发送和接收数据的基本操作。 **Erlang的并发特性**...

    emqx-4.4.3-otp24.2.1-windows-amd64.zip

    EMQX,全称为Erlang MQTT Broker,是一款基于Erlang OTP开发的开源MQTT消息代理,专门针对物联网(IoT)设计。这个“emqx-4.4.3-otp24.2.1-windows-amd64.zip”压缩包文件包含了EMQ X Broker的4.4.3版本,适配于运行...

    RabbitMQ_3.8.2--ErLang_otp_win64_22.2.zip

    **RabbitMQ 3.8.2 和 Erlang OTP Win64 22.2 安装指南** RabbitMQ 是一个广泛使用的开源消息代理和队列服务器,它基于 AMQP(Advanced Message Queuing Protocol)协议,适用于多种编程语言。在Windows系统上部署...

    Erlang 安装包(otp_win32_R16B03-1.part2)

    Erlang 安装包(otp_win32_R16B03-1.part2)

    AX3_OTP_Auth-1.0.4-py3-none-any.whl.zip

    标题 "AX3_OTP_Auth-1.0.4-py3-none-any.whl.zip" 暗示了这是一个与身份验证和Python编程相关的软件包。这个文件是压缩格式的ZIP,里面包含了至少两个文件:一个名为“使用说明.txt”的文本文件以及一个名为“AX3_...

    gen_server tasting 之超简单名称服务(再续)

    在IT行业中,`gen_server` 是Erlang OTP(开放电信平台)框架中的一个核心行为模块,用于构建可靠且容错的服务。它提供了一种模式,使得开发者可以编写并发、状态管理和故障恢复的服务器进程。在"gen_server tasting...

    rabbitmq-server3.7版本和otp_win64安装包

    **RabbitMQ 3.7 版本与 OTP_win64 安装详解** RabbitMQ 是一个基于 AMQP(Advanced Message Queuing Protocol)的消息中间件,它允许应用程序之间进行异步通信,确保数据可靠传输。3.7 版本是 RabbitMQ 的一个重要...

    AX3_OTP_Auth-1.0.3-py3-none-any.whl.zip

    标题中的"AX3_OTP_Auth-1.0.3-py3-none-any.whl.zip"揭示了这是一个软件包,具体来说是Python的第三方库,名为"AX3OTPAuth",版本号为1.0.3。".whl"是Python的轮子文件(Wheel File)格式,它是预编译的Python包,...

    otp-win64-25.1.2 rabbitmq-server-3.11.2

    标题中的"otp-win64-25.1.2"指的是Erlang OTP(Open Telephony Platform)的一个64位Windows版本,版本号为25.1.2。Erlang OTP是一个开源平台,主要用于构建高可用性、分布式和实时系统。它提供了强大的并发处理、...

    Erlang-otp_win64_23.0 和 rabbitmq-server-3.8.5

    2. **安装Erlang OTP**: 运行下载的安装包,按照向导指示进行安装。默认设置通常即可满足大多数需求,但你可以根据个人需求自定义安装路径。 3. **环境变量配置**: 安装完成后,确保Erlang的bin目录已添加到系统的...

    erlang-otp_mibs-19.3.6.4-1.el7.x86_64.rpm

    erlang-otp_mibs-19.3.6.4-1.el7.x86_64.rpm

    AX3_OTP_Auth-1.0.1-py3-none-any.whl.zip

    标题 "AX3_OTP_Auth-1.0.1-py3-none-any.whl.zip" 暗示了这是一个Python的软件包,其中包含了AX3 OTP Auth模块的1.0.1版本。OTP(One-Time Password)通常指的是一次性密码,用于增强安全性,尤其在身份验证过程中。...

    AX3_OTP_Auth-1.0.2-py3-none-any.whl.zip

    2. **OTP (One-Time Password) 认证**: "AX3_OTP_Auth" 这个名字表明这个库可能涉及到一次性密码(OTP)认证。OTP是一种安全的身份验证方法,用户在登录时需要输入一个只在特定时间内有效的密码,增加了账户的安全...

    AX3_OTP_Auth-1.0.5-py3-none-any.whl.zip

    标题 "AX3_OTP_Auth-1.0.5-py3-none-any.whl.zip" 暗示了这是一个Python库的压缩包,名为AX3_OTP_Auth,版本为1.0.5,适用于Python 3环境。"whl"标签表明这个库是以 Wheel 格式提供的,这是一种预编译的Python软件包...

    AX3_OTP_Auth-1.0.0-py3-none-any.whl.zip

    描述中的内容与标题相同,再次确认了我们处理的是一个名为`AX3_OTP_Auth`的Python库的版本1.0.0的`.whl`文件的压缩版。 标签 "whl" 进一步强调了该文件的性质,`.whl`文件是Python的Wheel格式,它解决了Python的`...

Global site tag (gtag.js) - Google Analytics