1

gen_fsm タイムアウトについて質問があります。2 つの状態を持つ gen_fsm のセットがあるとしましょう (将来はそれ以上になる可能性があります):idleこれは開始状態とworking.

gen_fsm は 5 秒ごとに特定のパラメータをチェックし、それに従って に留まるか、idleまたは に移動しworkingます。gen_fsm が に移動するときはいつでも、workingメッセージを ( を使用してgen_fsm:send_all_state_event/2) 他のすべての gen_fsm にidle送信workingworkingます。

ここで重要なのは、ステート タイムアウトに偏りを持たせたくないということです (たとえば、マシンが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 に答える