erlang gen_server 源码分析 1

 

首先,类型的语法,源代码中使用的-callback,现在的新的语法应该已经和-spec一样了,即前者的功能后者也可以实现了,因此在erlang编程设计中也是使用-spec。同时,这里的对于函数的测试,一般都是返回一个元组{ok, ...}。

    这里首先调用gen:start,后者通过start函数来调用do_spawn函数,do_spawn则调用proc_lib的start或者start_link函数,这里第二个参数是init_it,因此可以知道,调用gen_server的start或者start_link函数之后,proc_lib的start或者start_link函数最终将调用erlang的spawn_monitor或者spawn_link函数。

 

start_link(Mod,Args,Options)->

gen:start(?MODULE,link,Mod,Args,Options).

do_spawn(GenMod,link,Mod,Args,Options)->

    Time=timeout(Options),

    proc_lib:start_link(?MODULE,init_it,

            [GenMod,self(),self(),Mod,Args,Options],

            Time,

            spawn_opts(Options));

start_link(M,F,A)whenis_atom(M),is_atom(F),is_list(A)->

    start_link(M,F,A,infinity).

 

       反正一路调用下来,终于是进入init_it函数执行。这里case一行调用回调模块中的init函数。之后根据init的返回值来选择不同的loop循环来执行,或者停止等其他动作。

 

init_it(Starter,Parent,Name0,Mod,Args,Options)->

    Name=gen:name(Name0),

    Debug=gen:debug_options(Name,Options),

    HibernateAfterTimeout=gen:hibernate_after(Options),

    %%下面调用回调模块的init函数

    caseinit_it(Mod,Args)of%根据init函数返回值选择分支执行

    { ok, { ok,State}} ->

       proc_lib:init_ack(Starter, { ok,self()}),%告诉parent进程已经初始化了,初始化开始或者失败   

        loop(Parent,Name,State,Mod,infinity,HibernateAfterTimeout,Debug);%进入loop循环,infinity

    { ok, { ok,State,Timeout}} ->% infinity表示gen_server进程一直运行下去

       proc_lib:init_ack(

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值