美文网首页
gen_server启动,关闭,消息收发分析

gen_server启动,关闭,消息收发分析

作者: kyo1992 | 来源:发表于2020-07-05 11:26 被阅读0次

https://www.cnblogs.com/hzy1987/p/5441807.html
http://www.cnblogs.com/me-sa/archive/2011/12/20/erlang0023.html


介绍:

gen_server是OTP的一个behavior, 在behavior基础上快速构建出可用且可靠的功能.
behavior是进程模式的规范化,把代码分成两部分,一部分是通用部分(behavior模块),一部分是定制部分(回调模块).对于gen_server就是要把client/server的模型进行一个抽象和封装,把behavior和回调模块需要完成的职责分离开.


启动流程:

  1. 调用启动函数, start/3, start/4, start_link/3, start_link/4, 选择其中一个, 这里以常见的start_link/4为例,实际上是调用了gen:start, 第二个参数表示与父节点建立链接,即新启动的进程死掉后,会不会通知启动他的进程(父进程).
image.png
  1. 进入gen:start/6, 首先判断使用Name名字的进程是否已经存在, 若注册了直接返回already_start, 若未注册则调用do_spawn/6,进入创建进程前的准备.
image.png
  1. 进入do_spawn/6, 检查启动参数是否有超时限制, 然后调用proc_lib:start_link, 真正创建一个进程.
image.png
  1. 进入创建进程的阶段, 此时函数调用位于子进程, 调用init_it/6, 首先判断Name是否已经注册,与where类似,需要根据名字是全局(global),本节点(local),转发(via)而定, 未注册则进入init_it2函数.
image.png
  1. 进入init_it2/7, 实际直接调用gen_server:init_it.

  2. gen_server:init/7, 调用Mod:init/1, 调用逻辑模块的init函数,返回{ok,State}则创建成功,
    此时给父进程发送{ack,self(),{ok,self()}消息, proc_lib:sync_wait接收到后, 返回{ok,ChildPid}到父进程, 父进程的gen_server:start_link函数结束.

image.png

然后进程在运行状态通过loop方法来实现状态循环,loop方法的职责就是receive-evaluate,接受到消息,处理,更新进程状态,并把进程状态作为尾递归的参数传递回去, 此时一个gen_server创建完毕.
ps: proc_lib:start_link函数, 里面会同步等待子进程返回{ack,Pid,Return}消息.

image.png
  1. gen_server:loop/6, receive显示接受消息,然后调用decode_msg对消息进行处理.
image.png

消息发送与接收:

发送:
gen_server提供的方式有两种:

  1. call: 同步调用, 调用gen:call, 消息格式为{’$gen_call’, {self(),MRef}, Request}, monitor用于监控目标进程是否存在,
    同时返回MRef, 是一个唯一引用, 用于接收返回消息时做消息的模式匹配识别,对应对端的回调函数为
    handle_call. 同步调用本质上是erlang:send发送消息, 然后调用receive接收指定消息(MRef}的返回.
  2. cast: 异步调用, 调用gen:cast, 消息格式为{’$gen_cast, Request}.

接收:

gen_server:loop/6, 会不断receive接收消息, 然后调用decode_msg函数进行消息处理,这里就说说decode_msg.
对Msg进行模式匹配,

  1. {EXIT,Parent,Reanson}则表示受到终止进程的消息,调用terminate进入扫尾工作,例如关闭已打开的资源,
    文件,网络连接,打log,数据保存等.

  2. 其余则进入handle_msg处理,目前debug参数为[].
    handle_msg:

  3. 消息为{’$gen_call’, From, Msg}则表示发送方调用了 gen_server:call, 接收方调用
    Mod:handle_call处理.

  4. 消息为{’$gen_cast’,Msg}则表示发送方调用了 gen_server:cast, 接收方调用Mod:handle_cast处理.
    其他消息一般表示原生消息, 例如socket发来的消息, 发送方使用 ! 发来的消息, 与本进程建立连接的进程挂掉,

  5. 发送{‘EXIT’,Pid,Why}等, 接收方调用Mod:handle_info处理.

image.png

关闭进程方式:

让handle_call, handle_cast, 或handle_info最后返回 {stop,normal,State}消息, 然后就调用terminate函数, 调用Mod:terminate,
所以需要写一条接收关闭进程消息的处理函数.

image.png

相关文章

网友评论

      本文标题:gen_server启动,关闭,消息收发分析

      本文链接:https://www.haomeiwen.com/subject/axxvqktx.html