Erlang/Otp gen_server terminate

gen_server定义了6个callback接口:

init/1

handle_call/3

handle_cast/2

handle_info/2

terminate/2

code_change/3

对于callback的实现者来说,理解callback函数的触发点是最重要的,前4个callback的调用时机都很清晰,不讨论,只讨论terminate的调用。

terminate的被调用有如下几种情况:

1、handle_call返回{stop, Reason, Reply, StateN} -> terminate(Reason, StateN)

2、handle_info\handle_cast返回{stop, Reason, StateN} -> terminate(Reason, StateN)

3、handle_call\handle_cast\handle_cast抛出异常(在gen_server.erl中被捕获为{'EXIT', What}) -> terminate(What, State)

4、handle_call\handle_info\handle_cast 返回值非法 -> terminate({bad_return_value, Reply}, State)

5、收到来自Parent的{'EXIT', Parent, Reason}消息:

设置了一个timeout或者无限等待的情况下,supervisor是通过exit(Pid, shutdown)来通知子进程退出的,所以,若supervisor下的gen_server worker进程没有设为系统进程,worker进程不会受到来自Parent的Exit消息,故terminate不会被调用。

结论:

terminate被调用的方式有如下几种:

1、返回值触发

2、代码错误抛出异常被捕获

3、系统gen_server收到来自Parent的Exit消息

如果希望gen_server进程崩溃时terminate一定被调用到(exit(Pid, kill)除外),设为system进程即可。


以上仅仅是结论,通过查看源码,以及写测试代码得出。这里有一些用得到的测试代码:

测试代码

你可能感兴趣的:(erlang)