Erlang 并发错误处理

[b]这一章有三个关键的概念:link,exit signal, system process,现在就对这些做个总结:
[/b]
通常一个process是由另一个process创建,若我们不做任何处理,那么新创建的process(我们称:子process)和创建它的process(我们称:父process),在创建完成后将没有任何关系,任何瓜葛,生老病死都不会被对方感知,但是若我们有这样这一种需求(我工作中就有)某个线程执行一个很重要的task,若在执行过程中因为某个原因挂掉了,这种情况需要被感知并且重启继续执行。若是其他语言,我没想到什么好的方法,但是erlang确天然的提供这种支持(这也是它能够构建容错系统的原因),而它提供的支持手段就是[b]link[/b].

那什么是link呢? 譬如有两个process:Pid_A和Pid_B,当Pid_A调用link(Pid_B)方法时,就在Pid_A和Pid_B之前建立了一条“虚拟连接”,Pid_A就能够感知Pid_B的生老病死(注意,这个连接是[b]双向[/b]的,B挂了会告诉A,A挂了它也会告诉B,它们互相监督)

那么当B挂了,它是怎么告诉A的呢?并且A得知B挂了,它又如何处理?
process B挂掉的时候,会向link到它的所有processes广播一个[b]exit signal[/b],在这个exit signal中就包含process B为什么挂掉的原因,我们有几种方式设置这个挂掉的原因:
[b]显示方式[/b]:
exit(Reason) 当前process结束并且exit reason为参数Reason
exit(Pid, Reason) 向Pid process发送一个exit signal并且exit reason 为参数Reason
[b]隐式方式[/b]:
程序抛runtime error,Reason被自动设置成刚才抛错原因
[i][color=red][b]注意:若process正常退出,exit signal Reason为normal,这种exit signal不会对其他process(linked)有任何影响[/b][/color][/i]

当process A收到一个exit signal后,若它只是一个普通process,它将以同样Reason结束掉自己(这就叫不求同日生,但求同日死),但是如果link只有这种作用,那么它完全不能完成我们刚才说的那个需求:监督->发现process挂掉->重启。嘿嘿,这就是我们要说的最后一个概念:[b]system process[/b]。

若process A 是一个system process,当他收到exit signal,它将不会结束自己,而是把exit signal转变为一条{'EXIT',From,Reason}消息,放入到自己的mail-box中(其中参数From代表是哪个Process挂掉了,Reason表示挂掉的原因),也就是说system process能够捕获exit signal(而不是简单结束自己),这样当我们捕获到exit signal时(即收到一条{'EXIT',From,Reason}消息),就可以做出相应处理(譬如重启),从而起到监控作用。
[i][color=red][b]注意:若exit signal Reason为kill,那么这个exit signal将不能被捕获,即使你是system process;[/b][/color][/i]
[i][color=blue][b](以上是书上说的,但是我自己的测试结果是:调用exit(kill)发出的exit signal依然能够被system process捕获,而exit(Pid, kill)发出的exit signal是不能够被捕获的,关于这点,希望能跟大家求证)[/b][/color][/i]

现在贴下《Programming Erlang》中的一张图,它更清楚的说明了上述情况:
[img]http://dl.iteye.com/upload/attachment/0078/8235/90584cbf-e824-39b9-af25-eda8dbb457cc.png[/img]

ps:process_flag(trap_exit, true) 可以把一个普通process变为system process

最后,文中稍微涉及了一些race condition的概念(譬如两个process同时register(erl, Pid)),自己网上找了一帖子,说的还比较清楚:
[url]http://stackoverflow.com/questions/4366826/avoiding-a-race-condition[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值