Definitions
Exit signals are sent when processes crash
Exit Signals propagate through Links
Processes can trap exit signals
Complex Exit signal Propagation
Robust Systems can be made by Layering
Primitives For Exit Signal Handling
A Robust Server
Allocator with Error Recovery
Allocator Utilities
Definitions定义
Link 双向信号?
Exit Signal 传递进程结束信息
Error trapping 进程正确处理各种退出信号
Exit signals are sent when processes crash
进程异常崩溃时向所有连接进程发出错误信号
Exit Signals propagate through Links
如果进程连接方式如下:
A->B->C->D-E
那进程A崩溃会将Exit signal发送到B,如果B没有处理此信号而崩溃,则会依次传递下去
Processes can trap exit signals
如果进程处理了错误信号,则不会传递下去
Exit Signal Propagation Semantics
- 进程结束时,会产生一个正常或异常的退出信号,发送给所有连接的进程
- 进程在遇到没处理的异常退出信号时会崩溃,然后同样将信号传递给所有连接的进程
- 进程在一个receive操作中处理所有可能的信号
- BIFs和模式匹配出现的Error会发送自动退出信号给连接进程
Robust Systems can be made by Layering
分层创建系统可以使我们创建一个鲁棒的系统,如Level1处理所有Level2层的信号,Level2处理所有应用层的信号
一个设计优良的系统,我们可以不用写任何错误处理代码,因为错误能在底层被处理掉
Primitives For Exit Signal Handling
link(Pid)在进程自身和Pid进程之间创建一个双向连接
process_flag(trap_exit,true) 当前进程将错误信号转换成退出信号,可以被receive操作接收
exit(Reason)如:exit(failed_to_connect),其中exit(normal)表示接收信号的进程可以忽略此信号
A Robust Server
%如下的代码,客户端发出alloc以及release分别代表申请资源以及释放资源,如果在中途客户端崩溃掉,则资源得不到释放 top(Free, Allocated) -> receive {Pid, alloc} -> top_alloc(Free, Allocated, Pid); {Pid ,{release, Resource}} -> Allocated1 = delete({Resource,Pid},Allocated), top([Resource|Free], Allocated1) end. top_alloc([], Allocated, Pid) -> Pid ! no, top([], Allocated); top_alloc([Resource|Free], Allocated, Pid) -> Pid ! {yes, Resource}, top(Free, [{Resource,Pid}|Allocated]).
Allocator with Error Recovery
%下面的代码就处理了EXIT错误信息,并清除了资源 top_recover_alloc([], Allocated, Pid) -> Pid ! no, top_recover([], Allocated); top_recover_alloc([Resource|Free], Allocated, Pid) -> %% No need to unlink. Pid ! {yes, Resource}, link(Pid), top_recover(Free, [{Resource,Pid}|Allocated]). top_recover(Free, Allocated) -> receive {Pid , alloc} -> top_recover_alloc(Free, Allocated, Pid); {Pid, {release, Resource}} -> unlink(Pid), Allocated1 = delete({Resource, Pid}, Allocated), top_recover([Resource|Free], Allocated1); {'EXIT', Pid, Reason} -> %% No need to unlink. Resource = lookup(Pid, Allocated), Allocated1 = delete({Resource, Pid}, Allocated), top_recover([Resource|Free], Allocated1) end.
Allocator Utilities
delete(H, [H|T]) -> T; delete(X, [H|T]) -> [H|delete(X, T)]. lookup(Pid, [{Resource,Pid}|_]) -> Resource; lookup(Pid, [_|Allocated]) -> lookup(Pid, Allocated)