gen_fsm erlang超时

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秒

我有一个关于gen_fsm超时的问题。假设您有一组具有两种状态的gen_fsm(将来可能会更多):
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函数免费正确执行此操作。