gen_fsm erlang超时

时间:2012-03-05 11:27:29

标签: erlang gen-fsm

我对gen_fsm超时有疑问。让我们假设您有一组gen_fsm,其中包含两个状态(将来可以更多):idle这是起始状态working

gen_fsm检查特定参数的任何5秒钟,根据它将保留在idle或移至working。每当gen_fsm移动到working时,它都会向所有其他gen_fsm发送消息(使用gen_fsm:send_all_state_event/2):idle中的消息应移至workingworking中,不应该关心传入的消息。

现在,重点是我不希望在状态超时中出现偏差(例如,如果机器在working中持续3秒并且收到消息会发生什么?5秒超时不再有效,因为我想保留一个固定的超时,无论如何(这意味着应该在固定的时间触发超时消息)。

以下是我的解决方案的重要部分,它使用now()time:now_diff/2。无论如何我有一个很小的漂移,但自从谈论几秒钟后似乎很公平。

你认为它有效吗?

{ok, idle, #state{time = now()}, 5000}.

idle(timeout, State) ->
    %% do some operations
    {next_state, idle, State#state{time = now()}, 5000}.

working(timeout, State) ->
    %% do some other actions
    {next_state, working, State#state{time = now()}, 5000}.

handle_event(work, working, #state{time = Time} = State) ->
    Timeout = round(timer:now_diff(now(), Time) / 1000),
    {next_state, working, State, Timeout}.

handle_event(work, StateName, state{time = Time} = State) ->
    Timeout = round(timer:now_diff(now(), Time) / 1000),
    {next_state, working, State, Timeout}.

1 个答案:

答案 0 :(得分:4)

您可以使用timer:apply_interval来调用将事件发送到fsm的api函数。

或者您使用timer:send_interval发送您可以在gen_fsm的handle_info回调中处理的自定义消息。