标签:
link/1 and monitor/2 are 2 different ways of notifying (or know) that a process died. Thing is, these are really very different in nature and these differences are not widely understood by beginners. So let‘s shed some light on this subject!
Links are what makes it possible to have supervisor trees. As stated in the Error Handling section of the processes reference manual:
Erlang has a built-in feature for error handling between processes. Terminating processes will emit exit signals to all linked processes, which may terminate as well or handle the exit in some way.
The signal in question is the exit signal, and the links make this signal propagate through processes (i.e: up in the supervisor hierarchy). By default, this signal makes your processes terminate as well. Assume the following code:
Let‘s spawn of those, and try to link our shell to it:
As you can see, using gen_server:start_link/4 automatically creates a link between our shell and the newly started process. So when this new process terminates, our shell gets an exit signal, also crashes, but it gets automatically restarted (note how the self() code returned 2 different pids).
The Receiving Exit Signals section of the processes reference manual gives some more information:
The default behaviour when a process receives an exit signal with an exit reason other than normal, is to terminate and in turn emit exit signals with the same exit reason to its linked processes. An exit signal with reason normal is ignored.
A process can be set to trap exit signals by calling:
process_flag(trap_exit, true)
When a process is trapping exits, it will not terminate when an exit signal is received. Instead, the signal is transformed into a message {‘EXIT‘,FromPid,Reason} which is put into the mailbox of the process just like a regular message.
Let‘s now try the same thing, but capturing the exit signal with process_flag/2
:
As you can see, the shell didn‘t died, but got a message instead. Cool!
To sum up, and to quote the Processes entry in the OTP reference manual:
As a final note to links, there are a couple of interesting functions to know about:
Monitors are not links, they are a more relaxed way of knowing what happened to a process.
They use messages instead of signals, and these messages are not propagated like signals, so nothing happens to your process when a monitored process exits (except that you get a new message in your mailbox). Also, they are unidirectional and allow you to establish as many "monitors" as you want (remember how links limited the number of links between 2 processes to just 1). Quoting the manual:
An alternative to links are monitors. A process Pid1 can create a monitor for Pid2 by calling the BIF erlang:monitor(process, Pid2). The function returns a reference Ref.
If Pid2 terminates with exit reason Reason, a ‘DOWN‘ message is sent to Pid1:
{‘DOWN‘, Ref, process, Pid2, Reason}
Monitors are unidirectional. Repeated calls to erlang:monitor(process, Pid) will create several, independent monitors and each one will send a ‘DOWN‘ message when Pid terminates.
Now, to the very same source code we tried above, let‘s modify it to add a start/0 function:
Note the new start/0 call that uses gen_server:start/4 instead of gen_server:start_link/4, so we can avoid having our shell linked to the new process when trying it.
Let‘s try it in the shell:
So our shell, while still was informed about the exit of the other process, didn‘t die (because it didn‘t got an exit signal).
A couple of interesting functions related to monitoring:
So this brings up the question: should I link to or monitor my processes? Of course the answer is 42.. I mean, it depends. Use link if you:
Use monitor if you:
【转载】Erlang 中 link 和 monitor 的区别
标签:
原文地址:http://www.cnblogs.com/jimmysue/p/4518235.html