1

我对 gen_fsm 超时有疑问。假设您有一组具有两种状态的 gen_fsm(将来可能会更多):idle这是起始状态,而working.

任何 5 秒 gen_fsm 都会检查一个特定的参数,并据此将保留idle或移动到working. 每当 gen_fsm 移动到 时,它都会向所有其他 gen_fsmworking发送一条消息(使用):in 中的那些应该移动到,而 in 中的那个不应该关心传入的消息。gen_fsm:send_all_state_event/2idleworkingworking

现在,关键是我不想在状态超时中出现偏差(例如,如果机器在working3 秒内并收到一条消息会发生什么?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}.
4

1 回答 1

4

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

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

于 2012-03-05T13:33:41.023 回答