Erlang was originally developed as a language for telecommunications products, and because of this purpose, her strict requirements for error handling were determined. In addition to providing syntax such as exception and try catch, Erlang also supports two mechanisms for monitoring processes, Link and Monitor, so that all processes can be connected to form a whole. When a process exits with an error, other processes will receive a message notification that the process exits. With these features, it is not difficult to build a simple and robust system using erlang.
Process two-way monitoring-Link
The link method can establish a two-way link relationship between processes. When one of the processes exits, the other process will receive a message that the process has exited.
Example 1:
- -module(test).
- -export([start/0]).
- start() ->
- Pid = spawn(fun() ->loop() end),
- Pid2 = spawn(fun() ->loop_link(Pid) end),
- io:format("Pid ~p~nPid2 ~p~n", [Pid,Pid2]).
- loop_link(Pid) ->
- process_flag(trap_exit, true),
- erlang:link(Pid),
- receive
- Msg ->
- io:format("pid exit: ~p~n", [Msg])
- end.
- loop() ->
- process_flag(trap_exit, true),
- receive
- Msg ->
- io:format("pid2 exit: ~p~n", [Msg])
- end.
Run the code:
- 1> test:start().
- Pid <0.63.0>
- Pid2 <0.64.0>
- ok
- %% 杀掉Pid进程,进程Pid2收到通知
- 2> exit(pid(0,63,0),kill).
- pid exit: {'EXIT',<0.63.0>,killed}
- true
- 3> test:start().
- Pid <0.67.0>
- Pid2 <0.68.0>
- ok
- %% 杀掉Pid2进程,进程Pid收到通知
- 4> exit(pid(0,68,0),kill).
- pid2 exit: {'EXIT',<0.68.0>,killed}
- true
注:erlang进程默认不捕捉Exit信号,可以使用process_flag(trap_exit, true)改变这一默认行为。
注2:解除link监控用erlang:unlink(Pid)
进程单向监控-Monitor
Monitor方式则实现进程的单向监控,当被监控进程退出时,监控进程会收到该进程退出的消息。
例子2:
- -module(test).
- -export([start/0]).
- start() ->
- Pid = spawn(fun() ->loop() end),
- Pid3 = spawn(fun() ->loop_monitor(Pid) end),
- io:format("Pid ~p~nPid3 ~p~n", [Pid,Pid3]).
- loop_monitor(Pid) ->
- _MonitorRef = erlang:monitor(process, Pid),
- receive
- Msg ->
- io:format("pid exit: ~p~n", [Msg])
- end.
- loop() ->
- receive
- Msg ->
- io:format("pid3 exit: ~p~n", [Msg])
- end.
Run the code:
- 1> test:start().
- Pid <0.39.0>
- Pid3 <0.40.0>
- ok
- %% Kill the Pid process, the process Pid3 receives the notification
- 2> exit(pid(0,39,0),kill).
- pid exit: {'DOWN',#Ref<0.0.0.80>,process,<0.39.0>,killed}
- true
- 3> test:start().
- Pid <0.43.0>
- Pid3 <0.44.0>
- ok
- %% kill the Pid3 process, the process Pid does not receive notification
- 4> exit(pid(0,44,0),kill).
- true
Note: Use erlang:demonitor(MonitorRef) to remove monitor monitoring
Erlang will not issue a process exit notification if the process exits in the normal way
- 10> exit(pid(0,70,0), normal).
- true