Before we go into details of the supervision and error handling in an Erlang system, we need see how Erlang processes terminate, or in Erlang terminology, exit.
我们先来看看Erlang进程如何结束,或者说先来研究一下Erlang的关键字: exit.
A process which executes exit(normal) or simply runs out of things to do has a normal exit.
当进程通过执行exit(normal)或者进程所有代码都执行完成时,进程正常结束。
A process which encounters a runtime error (e.g. divide by zero, bad match, trying to call a function which doesn't exist etc) exits with an error, i.e. has an abnormal exit. A process which executes exit(Reason) where Reason is any Erlang term except the atom normal, also has an abnormal exit.
当进程遇到运行时错误(比如除0,非法匹配或者试图调用一个不存在的函数)会终止并产生一个错误,也就是说进程非正常终止。当进程通过执行exit(Reason),Reasons是指除了normal的其他任何Erlang term,也会使进程非正常终止。
An Erlang process can set up links to other Erlang processes. If a process calls link(Other_Pid) it sets up a bidirectional link between itself and the process called Other_Pid. When a process terminates, it sends something called a signal to all the processes it has links to.
Erlang进程可以连接到其他的Erlang进程。如果一个进程调用了link(Other_Pid)函数,这个进程就创建了一个它自己与进程Other_Pid之间的一个双向连接。当一个进程结束,它会发送一个信号给连接到它的进程。
The signal carries information about the pid it was sent from and the exit reason.
信号里面包含发送进程的PID以及终止原因。
The default behaviour of a process which receives a normal exit is to ignore the signal.
当一个进程收到一个正常终止信号时,它的默认处理方式是忽略这个信号。
The default behaviour in the two other cases (i.e. abnormal exit) above is to bypass all messages to the receiving process and to kill it and to propagate the same error signal to the killed process' links. In this way you can connect all processes in a transaction together using links and if one of the processes exits abnormally, all the processes in the transaction will be killed. As we often want to create a process and link to it at the same time, there is a special BIF, spawn_link which does the same as spawn, but also creates a link to the spawned process.
当一个进程收到一个非正常终止信号时,他的默认处理方式是忽略所有其他消息并且杀掉自己,然后发送一个同样的终止信号给连接到它的其他进程。(也就是同归于尽!!多浪漫的基情 :P)通过这种方式,你可以使用link把一个事务里面的所有进程连接在一起,这样的话,当他们中有一个进程非正常终止,事务中的所有其他进程都会被杀掉。由于我们经常需要在创建一个进程的同时连接到它,所以Erlang提供了一个内置函数spawn_link,他的功能基本与spawn相同,唯一不同的是会创建一个连接到spawn出来的进程。
It is possible to modify the default behaviour of a process so that it does not get killed when it receives abnormal exit signals, but all signals will be turned into normal messages on the format {'EXIT',FromPID,Reason} and added to the end of the receiving processes message queue. This behaviour is set by:
process_flag(trap_exit, true)
为了让进程收到非正常终止信号时不杀掉自己,我们有必要改变进程的默认处理方式。通过调用process_flag(trap_exit, true)函数,所有的异常终止信号都会被转换成普通的消息,消息格式为:{'EXIT',FromPID,Reason},这些消息会被添加到接收进程的消息队列。
There are several other process flags, see erlang(3). Changing the default behaviour of a process in this way is usually not done in standard user programs, but is left to the supervisory programs in OTP (but that's another tutorial).
通过这种方式改变进程的默认处理方式一般不会出现在标准的用户程序当中,这种方式经常使用的地方是在OPT的监督程序当中。