您的位置:首页 > 其它

Erlang的gen_server的terminate使用的几点总结

2014-01-09 22:43 302 查看
1、process_flag(trap_exit,true)的理解。
process_flag(trap_exit,true)是允许该进程捕获退出信号,将退出信号转成{'EXIT‘,From,Reason}存在自己的邮箱中,可以通过receive或模式匹配取出该消息去做某些事情。
在gen_server中,要想通过handle_info({'EXIT‘,From,Reason},State)匹配到的一个前提条件是gen_server进程必须有相link的进程保证其能够接收到exit信号
a、当{'EXIT',Parent,Reason}是由gen_server的父进程发来的时候,gen_server的terminate必执行,Erlang的设计思想是父进程退,必让子进程退,防止孤儿进程的出现;
b、当回调函数返回{stop,Reason,(Reply),State}时,terminate执行;
c、当{'EXIT',Other,Reason}是由其他非gen_server的父进程发来的时候,gen_server的terminate不会马上执行,该消息会传递给handle_info(Info,State),根据handle_info的返回值来决定是否执行terminate;

2、gen_server使用exit的几点总结。
exit(pid,Reason)表示向pid发送exit信号。
(1)当process_flag(trap_exit,false)时
Reason为normal, gen_server不退出, terminate不执行;
Reason为test、shutdown、kill、other时, gen_server退出, terminate不执行
(2)当process_flag(trap_exit,true)时
Reason为normanl test shutdown other时, gen_server终止, terminate执行
Reason为kill时, gen_server终止, terminate不执行
(3)执行exit(Pid,Reason)的进程,会向Pid的进程发送退出信号,让Pid进程退出,如果Pid进程设置了process_flag(trap_exit,true),Pid进程的邮箱会收到{'EXIT',执行exit的进程,State}。如:<0.20.0>进程执行了exit(pid(0.34,0),test)后,<0.34.0>进程设置了process_flag(trap_exit,true),邮箱会收到{'EXIT',<0.20.0>,State},<0.20.0>进程不会退出。
(4)exit(Reason),执行动作会使当前执行exit操作的进程退出。

3、gen_server的terminate会被执行的情况说明。
(1)不管是否设置了process_flag(trap_exit,true),gen_server收到了{stop,Reason,State}消息。如:gen_server的stop,通过调用handle_cast返回值为{stop,Reason,State};
(2)不管是否设置了process_flag(trap_exit,true),gen_server出现运行异常。如:gen_server收到了,没有匹配的消息,会导致gen_server的terminate发生;
(3)process_flag(trap_exit,true)时,gen_server
a、gen_server主动退出:正常退出执行了stop方法和异常退出(代码本身的问题所致,如无匹配,逻辑语法错误等或是执行了exit(pid,test/normal/shutdown/other))
b 、gen_server被动退出:init;stop(),c:q(),erlang:halt()

4、terminate永远不被执行的情况。
a、exit(pid,kill);
b、手动关闭shell,相当于关掉了erlang的运行环境;
c、process_flag(trap_exit,true)且gen_server有相连接的进程,同时gen_server中有handle_info({'EXIT',_,Reason},State),当收到除kill外的退出信号。

参考资料:http://blog.sina.com.cn/s/blog_96b8a1540101314t.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: