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.
一、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.
相关文章推荐
- 蔡军生先生第二人生的源码分析(五十七)OpenGL离屏渲染的相关函数
- MySQL源码分析(2):Mysql中的内存分配相关
- jrtplib 源码分析 (三) SOCKET
- 内核源码分析相关博客
- Orchard源码分析(6):Shell相关
- Orchard源码分析(5):Host相关(Orchard.Environment.DefaultOrchardHost类)
- GEF源码分析(一) eclipse的GEF相关项目说明
- PHP相关系列 - php与memcached服务器交互的分布式实现源码分析[memcache版]
- jrtplib 源码分析 (二) 数据包
- alsa lib源码分析
- libhdfs源码分析(3)
- 分享插件平台相关的源码分析——SharpDevelop、Composition Application Block、Eclipse OSGi、ObjectBuilder
- ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析
- Linux 学习数据专题【管理、编程、源码分析】——Linux相关图书选购指南
- libhdfs源码分析(5)
- Linux 学习数据专题【管理、编程、源码分析】——Linux相关图书选购指南
- ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析
- nginx 源码学习笔记(七)——内存分配相关源码分析
- ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析
- libpcap+PF_RING源码分析---前言(一)