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

时间:2022-06-01 20:16:59
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