Linking Processes• 进程可以调用link(Pid)来创建连接,连接之后,当一个进程死掉,另一个进程会收到一个exit的消息
• 如果进程不处理这个exit消息,默认情况下也会退出
• 这个连接工作在本地,也可以工作在多个节点上
on_exit 处理器on_exit(Pid, Fun) ->
spawn(fun() ->
process_flag(trap_exit, true),
link(Pid),
receive
{'EXIT', Pid, Why} ->
Fun(Why)
end
end).
错误处理详解
• 1. links
• 2. exit signal,退出信号
• 当一个进程死掉之后,一条退出信号会广播给所有和这个进程有link的进程
• 这个信号的会包括退出原因,但是这个原因有可能是任何erlang的数据结构
• 进程可以使用exit(Reason)来退出
• 进程完成了自己的工作而退出的时候,这时候的退出原因是normal,其他进程收到的消息是{'EXIT',Pid,normal}
• 进程Pid1可以发送一个退出消息给其他进程exit(Pid2,X).Pid2收到的消息是{'EXIT',Pid1,X},这样其他进程都以为Pid1死掉了,而Pid1还在继续运行,真阴险啊,呵呵,不过这样可以主动的杀掉其他进程
• 3. system process
• 调用process_flag(trap_exit,true)就可以将一个普通的进程编程系统进程
• 到一条非normal的退出消息送到一个普通进程的时候,普通进程就会挂掉
• 如果是到一个系统进程的话,将会编程一条普通的消息{'EXIT',Pid,Why}存放在邮箱里
•
• 另外,可以发送一个kill消息给一个进程,无论是不是系统进程,进程都将挂掉,并且广播一个killed的消息给链接的进程,这个功能要小心使用,一般是系统来杀掉没事干的进程用的
错误处理的一般模式• 1. 根本不管
• Pid = spawn(fun() -> ... end)
• 如果spawn出来的进程挂了,当前进程继续
• 2. 如果子进程非正常死亡,那我也不活了
• Pid = spawn_link(fun() -> ... end)
• 其实就是把自己和spawn出来的进程link在一起
• 前提是当前进程没有被设置成系统进程process_flag(trap_exit,true).
• 这样,如果spawn出来的进程非正常死亡了,那当前进程也挂掉
• 3. 自己处理spawn出来的进程的死亡...
process_flag(trap_exit, true),
Pid = spawn_link(fun() -> ... end),
...
loop(...).
loop(State) ->
receive
{'EXIT', SomePid, Reason} ->
%% do something with the error
loop(State1);
...
end
• 这样,除了kill消息外,其他所有的消息都可以被处理到了
高级错误处理,有点复杂-module(edemo1).
-export([start/2]).
start(Bool, M) ->
A = spawn(fun() -> a() end),
B = spawn(fun() -> b(A, Bool) end),
C = spawn(fun() -> c(B, M) end),
sleep(1000),
status(b, B),
status(c, C).
a() ->
process_flag(trap_exit, true),
wait(a).
b(A, Bool) ->
process_flag(trap_exit, Bool),
link(A),
wait(b).
c(B, M) ->
link(B),
case M of
{die, Reason} ->
exit(Reason);
{divide, N} ->
1/N,
wait(c);
normal ->
true
end.
wait(Prog) ->
receive
Any ->
io:format("Process ~p received ~p~n" ,[Prog, Any]),
wait(Prog)
end.
sleep(T) ->
receive
after T -> true
end.
status(Name, Pid) ->
case erlang:is_process_alive(Pid) of
true ->
io:format("process ~p (~p) is alive~n" , [Name, Pid]);
false ->
io:format("process ~p (~p) is dead~n" , [Name,Pid])
end.
Error Handling Primitives• @spec spawn_link(Fun) -> Pid 类似spawn,和spawn然后link不一样,这是一个原子操作
• @spec process_flag(trap_exit, true) 将当前进程设置为系统进程
• @spec link(Pid) -> true 将当前进程和Pid链接,这个链接是对等的,和哪方发起无关,如果Pid不存在,返回noproc,如果已经建立链接了,这次调用被忽略
• @spec unlink(Pid) -> true
• @spec exit(Why) -> none() 当前进程退出,然后广播一条退出消息给链接的进程(如果没被catch住)
• @spec exit(Pid, Why) -> true 发送一个退出信号给Pid
• @spec erlang:monitor(process, Item) -> MonitorRef ,这里的Item是一个PID或者是已注册的名字
• monitor是一个不对等的link,如果A monitor B,那么B挂了会发送一条退出消息给A,但是A挂了不会影响到B
•
分享到:
相关推荐
Concurrent Programming in ERLANG
Joe的那篇erlang论文 Programming Erlang + 源码包 Erlang Programming Concurrent Programming in Erlang efficiecy guide 资源齐全.希望能帮到你.
Erlang基础知识集锦 Erlang基础知识集锦 Erlang基础知识集锦 Erlang基础知识集锦 Erlang基础知识集锦 Erlang基础知识集锦
Erlang and OTP in Action teaches you to apply Erlang’s message passing model for concurrent programming–a completely different way of tackling the problem of parallel programming from the more ...
资源名称:Erlang语音学习资料汇总资源目录:【】Erlang程序设计【】[ManningPublications]ErlangandOTPinAction【】[NoStarchPress]LearnYouSomeErlangforGreatGood!ABeginner'sGuide【】[O'ReillyMedia]...
erlang 连接学习例子 最简单的通讯例子
The ideas in Erlang are difficult to trace to a single source. Many features of the language have been influenced and improved as a result of comments by our friends and colleagues of the Computer ...
erlang 中文基础教程erlang 中文基础教程
erlang中文基础教程
Programming Erlang + 源码包 Erlang Programming Concurrent Programming in Erlang Joe的那篇erlang论文 efficiecy guide
assumes no responsibility for errors or omissions,or for damages that may result from the use of information(including program listings)contained herein. Our Pragmatic courses,workshops,and other ...
erlang学习资料
学习erlang 开发游戏利器 erlang学习文档 erlang学习工具
erlang基础教程,比较适合初学者学习使用
Erlang_In_Anger pdf 语言
With this guide you'll learn how to write complex concurrent programs in Erlang, regardless of your programming background or experience. Written by leaders of the international Erlang community -- ...