• 停止
    • 在监督树中
    • 独立的Gen_Fsm
    • 处理其他消息

    停止

    在监督树中

    如果genfsm是监督树的一部分,那么不需要停止函数。它的督程会自动停止它。具体如何进行是通过督程中的[关闭策略_]($cfa29cf763f4b135.md#shutdown)集来定义。

    如果需要在终止前先进行清除操作,那么关闭策略必须是一个超时值,并且,gen_fsm必须在 init 函数里面设置成捕捉退出信号。当被要求关闭时,gen_fsm会调用回调函数 terminate(shutdown,StateName,StateData):

    1. init(Args) ->
    2. ...,
    3. process_flag(trap_exit, true),
    4. ...,
    5. {ok, StateName, StateData}.
    6.  
    7. ...
    8.  
    9. terminate(shutdown, StateName, StateData) ->
    10. ..code for cleaning up here..
    11. ok.

    独立的Gen_Fsm

    如果gen_fsm不是监督树的一部分,那么一个停止函数是有用的,例如:

    1. ...
    2. -export([stop/0]).
    3. ...
    4.  
    5. stop() ->
    6. gen_fsm:send_all_state_event(code_lock, stop).
    7. ...
    8.  
    9. handle_event(stop, _StateName, StateData) ->
    10. {stop, normal, StateData}.
    11.  
    12. ...
    13.  
    14. terminate(normal, _StateName, _StateData) ->
    15. ok.

    处理 stop 事件的回调函数返回一个元组 {stop,normal,StateData1},这里的 normal 指明了这是一个正常的终止,同时 StateData1 是gen_fsm状态数据的新值。这会使gen_fsm去调用terminate(normal, StateName, StateData1 ),然后优雅的终止。

    处理其他消息

    如果gen_fsm需要接收事件之外的消息,那么必须实现回调函数 handle_info(Info,StateName,StateData) 来处理这些消息。其他的消息比如退出消息,如果gen_fsm是联接到其他的进程(非督程)的,并且需要捕获退出信号。

    1. handle_info({’EXIT’, Pid, Reason}, StateName, StateData) ->
    2. ..code to handle exits here..
    3. {next_state, StateName1, StateData1}.