Reputation: 8874
I am learning erlang with book , In chapter 13, the first exercise is writing a function my_spawn, which catch exit message when spawned message crash/exited.
-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.
my confuse was, if after spawn_monitor, the Mod:Func(Args)
was finished, but the lib_misc:on_exit(...)
haven't setup, so the exit message will be lost, really ?
If that's correct, so how to catch this situation ?
[edit by Pascal]
I add the code for 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).
Upvotes: 0
Views: 198
Reputation: 14042
The first thing the function on_exit does is to spawn a process that set the process_flag trap_exit to true, thus it is "protected" from crashes, and will receive instead messages of the type: {'EXIT', Pid, Why}
.
On the next line it tries to link itself to Pid; 2 cases are possible:
{'EXIT', Pid, noproc}
and will call F(noproc).{'EXIT', Pid, Reason}
and call F(Reason).I don't understand why you speak about spawn_monitor, it is not used in your case. Anyway, if you replace link(Pid) by monitor(process,Pid) in the on_exit function, you even don't need to use trap_exit since the monitor function don't crash if the Pid is dead. In all cases it returns the message {'DOWN',MonitorReference,process,Pid,Reason}
. on_exit could be modified like this:
on_exit(Pid, Fun) ->
spawn(fun() ->
MonitorReference = monitor(process,Pid),
receive
{'DOWN',MonitorReference,process,Pid,Why} -> Fun(Why)
end
end).
Upvotes: 1
Reputation: 13154
No, the message (like all messages) will be queued. If the process receiving the message dies, though, its mailbox is lost.
If A does spawn_monitor
to spawn B, and B dies instantly, A is guaranteed to receive the DOWN message. If, however, A also dies, then everything in A's message queue is lost.
Upvotes: 1