【Erlang】gen_server terminate的坑

gen_server进程结束时, 会调用terminate函数, 但这并不是在任何情况下都成立的.

当gen_server进程主动关闭时, 也就是在回调函数 handle_xxx 中返回 {stop...} 的时候, terminate 是必然被调用的.

当gen_server进程处于监控树中, 被其监控进程关闭时, 情况就不一样了. 只有在这个进程设置了捕获退出信号, 即 process_flag(trap_exit, true), 并且其开启选项中设置了关闭超时时间, 而不是 brutal_kill, terminate才会被执行.

换句话说, 不捕获退出信号的gen_server被其监控进程关闭时, 会直接死掉, 不执行terminate函数!

看一下 gen_server 的源代码关于消息处理的部分:

decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) ->
    case Msg of
    {system, From, Req …
more ...

gen_server笔记

gen_server是erlang的OTP框架中最常用的“行为模式”了吧,至少几本erlang教材都是首 先介绍这个。

这东西用来做什么的呢?或者说,为什么要用这东西呢?由于我接触这东西不过几天, 理解尚非常粗浅,就我看来,用gen_server有以下几个好处:

  • 面向对像,封装数据与方法。gen_server内部需要维护一个状态State,并提供各种函数 给别人调用,就类似于其他语言中的“类”一样,把数据和方法封装在一起,防止数据被非法 改动。

  • 简化调用,屏蔽通讯。erlang中如果要自己实现远程过程调用(RPC)的话,需要自己 定义消息格式,自己编写封装与解包的代码,还要处理各种异常问题,这些gen_server 都帮我们做好了,只需要像平常使用函数一样直接调就用行了,省时省力还不出错。

  • 热代码替换等高级功能。 热代码替换是erlang大力宣传的一项特色功能,不停机维护 在生产上是非常美妙的事。不过这是高级功能,初学暂时用不上,书上也没多讲。

gen_server模板

gen_server是可以使用模板来写的,如下:

    -module().

    -behaviour(gen_server).

    %% API …
more ...