gen_fsm erlang超时
我有一个关于gen_fsm超时的问题。假设您有一组具有两种状态的gen_fsm(将来可能会更多):gen_fsm erlang超时,erlang,gen-fsm,Erlang,Gen Fsm,我有一个关于gen_fsm超时的问题。假设您有一组具有两种状态的gen_fsm(将来可能会更多):idle,这是启动状态和工作状态 任何5秒钟,gen_fsm将检查特定参数,并根据该参数将保持在空闲状态或移动到工作状态。每当一个gen_fsm移动到工作,它将向所有其他gen_fsm发送一条消息(使用gen_fsm:send_all_state_event/2):处于空闲状态的应移动到工作,而处于工作状态的应不关心传入的消息 现在,关键是我不希望状态超时出现偏差(例如,如果机器处于工作状态持续3秒
idle
,这是启动状态和工作状态
任何5秒钟,gen_fsm将检查特定参数,并根据该参数将保持在空闲状态
或移动到工作状态
。每当一个gen_fsm移动到工作
,它将向所有其他gen_fsm发送一条消息(使用gen_fsm:send_all_state_event/2
):处于空闲
状态的应移动到工作
,而处于工作
状态的应不关心传入的消息
现在,关键是我不希望状态超时出现偏差(例如,如果机器处于工作状态持续3秒并收到消息,会发生什么情况?5秒超时不再有效,因为我希望无论发生什么情况都保持固定超时(这意味着应在固定时间触发超时消息)
下面是我的解决方案的主要部分,它使用了now()
和time:now\u 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}.
您可以使用其中一个来调用将事件发送到fsm的api函数
或者您可以使用发送自定义消息,您可以在gen_fsm的回调中处理该消息。您可以使用其中一个来调用将事件发送到fsm的api函数
或者您可以发送自定义消息,您可以在gen_fsm的回调中处理该消息。事实上,我更改了gen_fsm:send_event_after(5000,超时)每个状态下的代码。您对此有何看法?这样做的缺点是,您可能会再次出现间隔漂移。要保持固定的间隔,您始终需要更正当前时间。计时器:*\u interval函数免费正确执行此操作。事实上,我更改了在每个状态下使用的代码gen\u fsm:send\u event\u after(5000,超时)。您对此有何看法?这样做的缺点是,您可能会再次出现间隔漂移。要保持固定间隔,您始终需要更正当前时间。计时器:*u interval函数免费正确执行此操作。