我对gen_fsm超时有疑问。让我们假设您有一组gen_fsm,其中包含两个状态(将来可以更多):idle
这是起始状态working
。
gen_fsm检查特定参数的任何5秒钟,根据它将保留在idle
或移至working
。每当gen_fsm移动到working
时,它都会向所有其他gen_fsm发送消息(使用gen_fsm:send_all_state_event/2
):idle
中的消息应移至working
在working
中,不应该关心传入的消息。
现在,重点是我不希望在状态超时中出现偏差(例如,如果机器在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}.
答案 0 :(得分:4)
您可以使用timer:apply_interval来调用将事件发送到fsm的api函数。
或者您使用timer:send_interval发送您可以在gen_fsm的handle_info回调中处理的自定义消息。