繁殖和接收的erlang竞态条件
我正在学习erlang,在第13章中,第一个练习是编写一个函数my_spawn,它在生成的消息崩溃/退出时捕获退出消息繁殖和接收的erlang竞态条件,erlang,Erlang,我正在学习erlang,在第13章中,第一个练习是编写一个函数my_spawn,它在生成的消息崩溃/退出时捕获退出消息 -module(my_spawn1). -compile(export_all). my_spawn(Mod,Func,Args) -> {M1, S1, Mi1} = os:timestamp(), Pid = spawn(Mod,Func,Args), lib_misc:on_exit(Pid, fun(Why) ->
-module(my_spawn1).
-compile(export_all).
my_spawn(Mod,Func,Args) ->
{M1, S1, Mi1} = os:timestamp(),
Pid = spawn(Mod,Func,Args),
lib_misc:on_exit(Pid, fun(Why) ->
{M2,S2,Mi2} = os:timestamp(),
ElapsedTime = (M2 - M1) * 1000000 + (S2 - S1) * 1000 + (Mi2-Mi1),
io:format("~p died with:~p~n consume time:~p(ms)", [Pid,Why,ElapsedTime]),
end),
Pid.
我的困惑是,如果在spawn_监视器之后,Mod:Func(Args)
已经完成,但是退出(…)上的lib_misc:on_exit(…)还没有设置,那么退出消息就会丢失,真的吗
如果这是正确的,那么如何抓住这种情况呢
[用Pascal编辑]
我添加了lib_misc:on_exit/2的代码
on_exit(Pid, Fun) ->
spawn(fun() ->
process_flag(trap_exit, true), %% <label id="code.onexit1"/>
link(Pid), %% <label id="code.onexit2"/>
receive
{'EXIT', Pid, Why} -> %% <label id="code.onexit3"/>
Fun(Why) %% <label id="code.onexit4"/>
end
end).
on_退出(Pid,Fun)->
繁殖(乐趣()->
进程标志(陷阱退出,真),%%
链路(Pid),%
接收
{'EXIT',Pid,为什么}->%%
乐趣(为什么)%%
结束
(完)。
否,消息(与所有消息一样)将排队。但是,如果接收消息的进程终止,则其邮箱将丢失
如果A确实spawn_monitor
生成B,并且B立即死亡,则A保证接收到停机消息。但是,如果A也死亡,则A的消息队列中的所有内容都将丢失。退出上的函数所做的第一件事是生成一个进程,该进程将进程标志trap\u exit设置为true,因此它将受到“保护”以防崩溃,并将接收以下类型的消息:{'exit',Pid,Why}
在下一行,它试图将自己链接到Pid;可能有两种情况:
- Pid不存在(错误的值,已经死了…),那么on_退出进程将收到消息
{'exit',Pid,noproc}
,并调用F(noproc)
- Pid存在,则on_退出进程将在接收时等待,直到进程Pid因某种原因消失。on_exit将接收
{'exit',Pid,Reason}
并调用F(Reason)
我不明白你为什么说spawn_monitor,它不用于你的案例。无论如何,如果在on_exit函数中用monitor(process,Pid)替换link(Pid),甚至不需要使用trap_exit,因为如果Pid失效,monitor函数不会崩溃。在所有情况下,它都返回消息{'DOWN',MonitorReference,process,Pid,Reason}
。on_出口可以修改如下:
on_exit(Pid, Fun) ->
spawn(fun() ->
MonitorReference = monitor(process,Pid),
receive
{'DOWN',MonitorReference,process,Pid,Why} -> Fun(Why)
end
end).
很好,如果监视器进程在接收之前退出,但在创建监视器之后退出,会发生什么?我使用的是监视器,而不是系统进程,该进程将陷阱的进程标志设置为真/你是对的,noproc或noconnection将是原因这是否意味着在创建进程时创建邮箱,即使你没有对其调用接收命令?是的,邮箱是使用进程创建的,它可以在到达任何接收语句之前存储传入的消息。