test_gen_server:start().
gen_server: test_gen_server init ! in Module: test_gen_server at Line: 35
{ok,<0.39.0>}
7> erlang:exit(Pid2, kill).
true
8> erlang:is_process_alive(Pid2).
false
测试结果表明,向 test_gen_server 发送 非normal 外的任何退出消息, test_gen_server 进程都会终止,且不会调用 ?MODULE:terminate/2 函数。
通过看 supervisor:shutdown/2 函数可知,在子进程退出设置 非brutal_kill 时, supervisor 在结束子进程时,会先发一条 shutdown 退出消息给子进程并等待子进程退出完毕,若退出超时则再次发送一条 kill 的退出消息给子进程,让子进程无条件退出。
所以如果子进程没有设置 trap_exit 进程标记,则子进程会在则收到 shutdown 之后就直接无条件退出了而不调用 ?MODULE:terminate/2 函数;
而设置 trap_exit 的话,子进程调用 ?MODULE:terminate/2 并退出,其退出原因是 shutdown。
通过看 gen_server:decode_msg/8 函数可知,gen_server 进程在收到 Parent 的任何 {'EXIT', Parent, Reason} 消息的时候(如父进程发送的 {'EXIT', Parent, shutdown} 消息),最终都会调用 ?MODULE:terminate/2 函数进行退出。