Erlang and process_flag(trap_exit, true)
After watching the Pragmatic Studio screen casts on Erlang, the last video on Supervisors mentioned that in order for a supervisor to get a开发者_如何学C notification about one of its children so it can properly restart it, the child should register with process_flag(trap_exit, true)
. Perhaps I just misunderstood the author (and chances are VERY high that I did misunderstand), but I thought supervisors automagically know when their children die (probably through spawn_link or something similar in the background). Is this really necessary? When should one use process_flag(trap_exit, true) in a real world case because the documentation explicitly states the following:
http://www.erlang.org/doc/man/erlang.html#process_flag-2
process_flag(trap_exit, Boolean)
When trap_exit is set to true, exit signals arriving to a process are converted to {'EXIT', From, Reason} messages, which can be received as ordinary messages. If trap_exit is set to false, the process exits if it receives an exit signal other than normal and the exit signal is propagated to its linked processes. Application processes should normally not trap exits.``
You have 3 idioms:
1/ I don't care if my child process dies:
spawn(...)
2/ I want to crash if my child process crashes:
spawn_link(...)
3/ I want to receive a message if my child process terminates (normally or not):
process_flag(trap_exit, true),
spawn_link(...)
Please see this example and try different values (inverse with 2 or 0 to provoke an exception, and using trap_exit or not):
-module(play).
-compile(export_all).
start() ->
process_flag(trap_exit, true),
spawn_link(?MODULE, inverse, [2]),
loop().
loop() ->
receive
Msg -> io:format("~p~n", [Msg])
end,
loop().
inverse(N) -> 1/N.
Supervisors use links and trap exits so they can keep track of their children and restart them when necessary. Child processes do not have to trap exits to be properly managed by their supervisors, indeed they should only trap when they specifically need to know that some process to which they are linked dies and they don't want to crash themselves.
The OTP behaviours are able to properly handle supervision if they are trapped or not trapped.
In Erlang, processes can be linked together. These links are bi-directional. Whenever a process dies, it sends an exit signal to all linked processes. Each of these processes will have the trapexit flag enabled or disabled. If the flag is disabled (default), the linked process will crash as soon as it gets the exit signal. If the flag has been enabled by a call to system_flag(trap_exit, true)
, the process will convert the received exit signal into an exit message and it will not crash. The exit message will be queued in its mailbox and treated as a normal message.
If you're using OTP supervisors, they take care of the trap_exit flags and details for you, so you don't have to care about it.
If you're implementing a supervision mechanism, which is probably what the screen-cast is about (haven't seen it), you will have to take care of the trap_exit thing.
精彩评论