gen_server实现

本文详细解析了Erlang OTP中的gen_server行为模块,从gen_server的启动过程、gen_server:call的实现、cast及abcast的消息发送、do_multi_call的多节点调用以及stop时的关闭流程,阐述gen_server如何处理消息并维持服务的稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gen_server是erlang otp封装的beheivor模块。
一、gen_server start初始化过程
1、gen_server_start*启动进程,初始化数据,进入loop。gen_server_start*调用gen:start(通过proc_lib:start*创建进程)创建进程。
2、gen执行gen:init_it方法,gen:init_it通过调用gen_server:init_it,gen_server:init_it调用Mod:init实现模块回调,回调成功,执行proc_lib:init_ack,然后进入gen_server:loop等待消息。
3、gen_server:loop收到消息后调用回调模块mod:handle_call mod:handle_cast mod:handle_info处理消息,处理完成后执行gen_server:loop。
4、如果异常,调用gen_server:terminate处理异常,该函数会掉用回调模块mod:terminate执行异常处理,并退出进程exit

二、gen_server:call 
1、gen_server:call通过调用gen:call实现call的。gen:call处理进程信息,然后调用gen:do_call来实现call动作
2、do_call 先调用erlang:monitor监控进程,然后调用erlang:send发送消息,receive reply或者DOWN消息,解除监控erlang:demonitor。如果进程无法监控(crash),监控节点monitor_node(Node,false) ,直接发消息给进程,receive reply或者nodedown,结束节点监控monitor_node(Node,false)。
3、当监控进程时会进行节点连接,所有在发消息时可以认为是已连接状态,设置参数noconnect。

do_call( Process , Label , Request , Timeout ) ->
    %% We trust the arguments to be correct, i.e
    %% Process is either a local or remote pid,
    %% or a {Name, Node} tuple (of atoms) and in this
    %% case this node (node()) _is_ distributed and Node =/= node().
         Node = case Process of
                           { _S , N } when is_atom( N ) ->
                                   N ;
                           _ when is_pid( Process ) ->
                                   node( Process )
                   end ,
         try erlang:monitor(process, Process ) of
                 Mref ->
                         %% If the monitor/2 call failed to set up a connection to a
                         %% remote node, we don't want the '!' operator to attempt
                         %% to set up the connection again. (If the monitor/2 call
                         %% failed due to an expired timeout, '!' too would probably
                         %% have to wait for the timeout to expire.) Therefore,
                         %% use erlang:send/3 with the 'noconnect' option so that it
                         %% will fail immediately if there is no connection to the
                         %% remote node.
                        
                         catch erlang:send(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值