您的位置:首页 > 其它

proc_lib:spawn相关源码分析

2017-06-09 18:28 302 查看
proc_lib中所有关于进程相关的方法都是在bif里的spawn相关方法上封装实现的。主要做进程字典'$ancestors' '$initial_call'的初始化和crash报告、退出处理。
一、proc_lib:spawn*相关函数实现
1、proc_lib:spawn* 相关函数通过调用相应的erlang:spawn*方法,执行proc_lib:init_p方法实现。
2、proc_lib_init_p进行'$ancestors' '$initial_call'进程字典初始化,并执行进程要执行的方法,如果执行异常,则执行proc_lib:exit_p处理异常,做crash报告,并执行exit退出。
-spec
init_p(pid(), [pid()], function())
->
term().
init_p(Parent,
Ancestors,
Fun)
when
is_function(Fun)
->
[align=left]    put('$ancestors', [Parent|Ancestors]),[/align]
    {module,Mod}
= erlang:fun_info(Fun, module),
    {name,Name}
= erlang:fun_info(Fun, name),
    {arity,Arity}
= erlang:fun_info(Fun, arity),
[align=left]    put('$initial_call', {Mod,Name,Arity}),[/align]
   
try
[align=left]        Fun()[/align]
   
catch
        Class:Reason
->
            exit_p(Class,
Reason)
   
end.
-spec
init_p(pid(), [pid()], atom(), atom(), [term()])
->
term().
init_p(Parent,
Ancestors,
M,
F,
A)
when
is_atom(M),
is_atom(F), is_list(A)
->
[align=left]    put('$ancestors', [Parent|Ancestors]),[/align]
    put('$initial_call', trans_init(M,
F,
A)),
    init_p_do_apply(M,
F,
A).
init_p_do_apply(M,
F,
A)
->
   
try
        apply(M,
F,
A)
   
catch
        Class:Reason
->
            exit_p(Class,
Reason)

   
end.

exit_p(Class,
Reason)
->
   
case
get('$initial_call')
of
        {M,F,A}
when
is_atom(M),
is_atom(F), is_integer(A)
->
           
MFA
= {M,F,make_dummy_args(A,
[])},
            crash_report(Class,
Reason,
MFA),
[align=left]            exit(Reason);[/align]
        _
->
           
%% The process dictionary has been cleared or
           
%% possibly modified.
            crash_report(Class,
Reason, []),
[align=left]            exit(Reason)[/align]
   
end.

二、proc_lib:start*相关函数实现
1、proc_lib:start*相关函数通过调用proc_lib:spawn*相关方法实现进程创建,然后调用proc_lib:sync_wait等待ack消息,实现同步。

sync_wait(Pid,
Timeout)
->
   
receive
        {ack,
Pid,
Return}
->
           
Return;
        {'EXIT',
Pid,
Reason}
->
            {error,
Reason}
   
after
Timeout
->
[align=left]            unlink(Pid),[/align]
            exit(Pid,
kill),
[align=left]            flush(Pid),[/align]
[align=left]            {error, timeout}[/align]
   
end.
-spec
flush(pid())
->
'true'.
flush(Pid)
->
   
receive
        {'EXIT',
Pid,
_}
->
[align=left]            true[/align]
   
after
0
->
[align=left]            true[/align]
   
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  erlang spawn