檢視原始碼 gen_fsm 行為 (stdlib v6.2)

已棄用,並在 OTP 20 中被 gen_statem 取代。

遷移至 gen_statem

以下是一個將 gen_fsm 轉換為 gen_statem 的簡單範例。此範例來自先前 gen_fsm 的使用者指南。

-module(code_lock).
-define(NAME, code_lock).
%-define(BEFORE_REWRITE, true).

-ifdef(BEFORE_REWRITE).
-behaviour(gen_fsm).
-else.
-behaviour(gen_statem).
-endif.

-export([start_link/1, button/1, stop/0]).

-ifdef(BEFORE_REWRITE).
-export([init/1, locked/2, open/2, handle_sync_event/4, handle_event/3,
     handle_info/3, terminate/3, code_change/4]).
-else.
-export([init/1, callback_mode/0, locked/3, open/3,
     terminate/3, code_change/4]).
%% Add callback__mode/0
%% Change arity of the state functions
%% Remove handle_info/3
-endif.

-ifdef(BEFORE_REWRITE).
start_link(Code) ->
    gen_fsm:start_link({local, ?NAME}, ?MODULE, Code, []).
-else.
start_link(Code) ->
    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
-endif.

-ifdef(BEFORE_REWRITE).
button(Digit) ->
    gen_fsm:send_event(?NAME, {button, Digit}).
-else.
button(Digit) ->
    gen_statem:cast(?NAME, {button,Digit}).
    %% send_event is asynchronous and becomes a cast
-endif.

-ifdef(BEFORE_REWRITE).
stop() ->
    gen_fsm:sync_send_all_state_event(?NAME, stop).
-else.
stop() ->
    gen_statem:call(?NAME, stop).
    %% sync_send is synchronous and becomes call
    %% all_state is handled by callback code in gen_statem
-endif.

init(Code) ->
    do_lock(),
    Data = #{code => Code, remaining => Code},
    {ok, locked, Data}.

-ifdef(BEFORE_REWRITE).
-else.
callback_mode() ->
    state_functions.
%% state_functions mode is the mode most similar to
%% gen_fsm. There is also handle_event mode which is
%% a fairly different concept.
-endif.

-ifdef(BEFORE_REWRITE).
locked({button, Digit}, Data0) ->
    case analyze_lock(Digit, Data0) of
    {open = StateName, Data} ->
        {next_state, StateName, Data, 10000};
    {StateName, Data} ->
        {next_state, StateName, Data}
    end.
-else.
locked(cast, {button,Digit}, Data0) ->
    case analyze_lock(Digit, Data0) of
    {open = StateName, Data} ->
        {next_state, StateName, Data, 10000};
    {StateName, Data} ->
        {next_state, StateName, Data}
    end;
locked({call, From}, Msg, Data) ->
    handle_call(From, Msg, Data);
locked({info, Msg}, StateName, Data) ->
    handle_info(Msg, StateName, Data).
%% Arity differs
%% All state events are dispatched to handle_call and handle_info help
%% functions. If you want to handle a call or cast event specifically
%% for this state you would add a special clause for it above.
-endif.

-ifdef(BEFORE_REWRITE).
open(timeout, State) ->
     do_lock(),
    {next_state, locked, State};
open({button,_}, Data) ->
    {next_state, locked, Data}.
-else.
open(timeout, _, Data) ->
    do_lock(),
    {next_state, locked, Data};
open(cast, {button,_}, Data) ->
    {next_state, locked, Data};
open({call, From}, Msg, Data) ->
    handle_call(From, Msg, Data);
open(info, Msg, Data) ->
    handle_info(Msg, open, Data).
%% Arity differs
%% All state events are dispatched to handle_call and handle_info help
%% functions. If you want to handle a call or cast event specifically
%% for this state you would add a special clause for it above.
-endif.

-ifdef(BEFORE_REWRITE).
handle_sync_event(stop, _From, _StateName, Data) ->
    {stop, normal, ok, Data}.

handle_event(Event, StateName, Data) ->
    {stop, {shutdown, {unexpected, Event, StateName}}, Data}.

handle_info(Info, StateName, Data) ->
    {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
-else.
-endif.

terminate(_Reason, State, _Data) ->
    State =/= locked andalso do_lock(),
    ok.
code_change(_Vsn, State, Data, _Extra) ->
    {ok, State, Data}.

%% Internal functions
-ifdef(BEFORE_REWRITE).
-else.
handle_call(From, stop, Data) ->
     {stop_and_reply, normal,  {reply, From, ok}, Data}.

handle_info(Info, StateName, Data) ->
    {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
%% These are internal functions for handling all state events
%% and not behaviour callbacks as in gen_fsm
-endif.

analyze_lock(Digit, #{code := Code, remaining := Remaining} = Data) ->
     case Remaining of
         [Digit] ->
         do_unlock(),
         {open,  Data#{remaining := Code}};
         [Digit|Rest] -> % Incomplete
             {locked, Data#{remaining := Rest}};
         _Wrong ->
             {locked, Data#{remaining := Code}}
     end.

do_lock() ->
    io:format("Lock~n", []).
do_unlock() ->
    io:format("Unlock~n", []).

OTP 19 文件

模組

gen_fsm

模組摘要

通用有限狀態機行為。

描述

此行為模組提供一個有限狀態機。使用此模組實作的通用有限狀態機程序 (gen_fsm) 具有一組標準的介面函數,並包含追蹤和錯誤報告的功能。它也適用於 OTP 監督樹。如需更多資訊,請參閱 OTP 設計原則

gen_fsm 程序假設所有特定部分都位於一個回呼模組中,該模組匯出一組預先定義的函數。行為函數與回呼函數之間的關係如下:

gen_fsm module                    Callback module
--------------                    ---------------
gen_fsm:start
gen_fsm:start_link                -----> Module:init/1

gen_fsm:stop                      -----> Module:terminate/3

gen_fsm:send_event                -----> Module:StateName/2

gen_fsm:send_all_state_event      -----> Module:handle_event/3

gen_fsm:sync_send_event           -----> Module:StateName/3

gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4

-                                 -----> Module:handle_info/3

-                                 -----> Module:terminate/3

-                                 -----> Module:code_change/4

如果回呼函數失敗或傳回錯誤的值,gen_fsm 程序會終止。

gen_fsm 程序會按照 sys(3) 中所述的方式處理系統訊息。sys 模組可用於除錯 gen_fsm 程序。

請注意,gen_fsm 程序不會自動捕獲退出訊號,必須在回呼模組中明確啟動。

除非另有說明,否則如果指定的 gen_fsm 程序不存在或指定了錯誤的參數,此模組中的所有函數都會失敗。

如果回呼函數指定 hibernate 而不是逾時值,則 gen_fsm 程序可以進入休眠(請參閱 erlang:hibernate/3)。如果伺服器預計會閒置很長時間,這會很有用。然而,請謹慎使用此功能,因為休眠意味著至少兩次的垃圾回收(在休眠時和喚醒後不久),而且您不希望在每次呼叫忙碌的狀態機之間執行此操作。

回呼函數

請參閱回呼函數章節,了解要從 gen_fsm 回呼模組匯出的函數。

狀態名稱表示狀態機的狀態。

狀態資料表示實作狀態機的 Erlang 程序的內部狀態。

摘要

類型

回覆目的地。請參閱 reply/2

FSM 名稱規格:localglobalvia 已註冊。

FSM 參考 pid/0 或已註冊的 fsm_name/0

啟動選項,適用於 start/3,4start_link/3,4 函數。

回呼:已棄用

在升級/降級期間更新內部狀態資料

format_status/2 已棄用

提供描述目前 gen_fsm 程序狀態的術語的可選函數。

處理非同步事件。

處理傳入的訊息

init(Args) 已棄用

初始化程序和內部狀態名稱狀態資料

處理非同步事件。

處理同步事件。

在終止之前清除。

函數

取消通用 FSM 中的內部計時器。

進入 gen_fsm 接收迴圈。

enter_loop/5 已棄用

進入 gen_fsm 接收迴圈。

向呼叫者傳送回覆。

將事件非同步傳送至通用 FSM。

將事件非同步傳送至通用 FSM。

在通用 FSM 中延遲傳送內部事件。

建立未註冊的獨立 gen_fsm 程序。

建立獨立的 gen_fsm 程序。

在監督樹中建立未註冊的 gen_fsm 程序。

在監督樹中建立 gen_fsm 程序。

在通用 FSM 中內部傳送逾時事件。

同步停止通用 FSM。

將事件同步傳送至通用 FSM。

將事件同步傳送至通用 FSM。

類型

連結到此類型

enter_loop_opt()

檢視原始碼 (未匯出)
-type enter_loop_opt() :: {debug, Dbgs :: [sys:debug_option()]}.

啟動選項,適用於 enter_loop/4,5,6start/3,4start_link/3,4 函數。

請參閱 start_link/4

-type from() :: {To :: pid(), Tag :: term()}.

回覆目的地。請參閱 reply/2

連結到此類型

fsm_name()

檢視原始碼 (未匯出)
-type fsm_name() ::
          {local, LocalName :: atom()} |
          {global, GlobalName :: term()} |
          {via, RegMod :: module(), ViaName :: term()}.

FSM 名稱規格:localglobalvia 已註冊。

當啟動 gen_fsm 時使用。請參閱 start_link/4

連結到此類型

fsm_ref()

檢視原始碼 (未匯出)
-type fsm_ref() ::
          pid() |
          (LocalName :: atom()) |
          {Name :: atom(), Node :: atom()} |
          {global, GlobalName :: term()} |
          {via, RegMod :: module(), ViaName :: term()}.

FSM 參考 pid/0 或已註冊的 fsm_name/0

例如,在 send_event/2 中使用,以指定伺服器。

連結到此類型

start_opt()

檢視原始碼 (未匯出)
-type start_opt() ::
          {timeout, Time :: timeout()} | {spawn_opt, [proc_lib:start_spawn_option()]} | enter_loop_opt().

啟動選項,適用於 start/3,4start_link/3,4 函數。

請參閱 start_link/4

回呼:已棄用

連結到此回呼

code_change(OldVsn, StateName, StateData, Extra)

檢視原始碼 (選用)
此回呼已棄用。回呼 gen_fsm:code_change(_,_,_,_) 已棄用;請改用 'gen_statem' 模組。
-callback code_change(OldVsn, StateName, StateData, Extra) -> {ok, NextStateName, NewStateData}
                         when
                             OldVsn :: Vsn | {down, Vsn},
                             Vsn :: term(),
                             StateName :: atom(),
                             NextStateName :: atom(),
                             StateData :: term(),
                             NewStateData :: term(),
                             Extra :: term().

在升級/降級期間更新內部狀態資料

gen_fsm 程序在發布升級/降級期間更新其內部狀態資料時,會調用此函式。也就是說,當 appup 檔案中給定指令 {update, Module, Change, ...},其中 Change = {advanced, Extra} 時;請參閱 OTP 設計原則中的發布處理說明。 OTP 設計原則

對於升級,OldVsnVsn,而對於降級,OldVsn{down, Vsn}Vsn 由回呼模組 Module 的舊版本的 vsn 屬性定義。如果沒有定義此類屬性,則版本是 Beam 檔案的校驗和。

StateName 是目前的狀態名稱,而 StateDatagen_fsm 程序的內部狀態資料

Extra 是從更新指令的 {advanced, Extra} 部分「原樣」傳遞。

此函式會傳回新的目前狀態名稱和更新的內部資料。

連結到此回呼

format_status/2

檢視原始碼 (選用)
此回呼已棄用。回呼 gen_fsm:format_status(_,_) 已棄用;請改用 'gen_statem' 模組。
-callback format_status(Opt, nonempty_improper_list(PDict, [StateData])) -> Status
                           when
                               Opt :: normal | terminate,
                               PDict :: [{Key :: term(), Value :: term()}],
                               StateData :: term(),
                               Status :: term().

提供描述目前 gen_fsm 程序狀態的術語的可選函數。

第二個引數是 [PDict, StateData],也就是說,一個依序包含 2 個元素的清單。

注意

此回呼為選用,因此回呼模組不需要匯出它。gen_fsm 模組提供了此函式的預設實作,會傳回回呼模組的 狀態資料

在以下情況下,gen_fsm 程序會調用此函式

  • 呼叫 sys:get_status/1,2 之一來取得 gen_fsm 狀態。在此情況下,Opt 會設定為原子 normal
  • gen_fsm 程序異常終止並記錄錯誤。在此情況下,Opt 會設定為原子 terminate。

此函式可用於變更這些情況下的 gen_fsm 狀態的格式和外觀。希望變更 sys:get_status/1,2 傳回值以及其狀態在終止錯誤記錄中顯示方式的回呼模組,會匯出 format_status/2 的實例,此實例會傳回描述 gen_fsm 程序目前狀態的詞彙。

PDictgen_fsm 程序的程序字典的目前值。

StateDatagen_fsm 程序的內部狀態資料

此函式會傳回 Status,一個變更 gen_fsm 程序目前狀態和狀態詳細資訊的詞彙。對於 Status 可以採用的格式沒有限制,但是對於 sys:get_status/1,2 的情況(當 Optnormal 時),Status 值的建議格式為 [{data, [{"StateData", Term}]}],其中 Term 提供 gen_fsm 狀態資料 的相關詳細資訊。不強制遵循此建議,但是這會使回呼模組狀態與 sys:get_status/1,2 傳回值的其餘部分保持一致。

此函式的一個用途是傳回壓縮的替代狀態資料表示法,以避免在記錄檔中列印大型狀態詞彙。

連結到此回呼

handle_event(Event, StateName, StateData)

檢視原始碼
此回呼已棄用。回呼 gen_fsm:handle_event(_,_,_) 已棄用;請改用 'gen_statem' 模組。
-callback handle_event(Event, StateName, StateData) -> Result
                          when
                              Event :: term(),
                              StateName :: atom(),
                              StateData :: term(),
                              Result ::
                                  {next_state, NextStateName, NewStateData} |
                                  {next_state, NextStateName, NewStateData, Timeout} |
                                  {next_state, NextStateName, NewStateData, hibernate} |
                                  {stop, Reason, NewStateData},
                              NextStateName :: atom(),
                              NewStateData :: term(),
                              Timeout :: timeout(),
                              Reason :: term().

處理非同步事件。

每當 gen_fsm 程序收到使用 send_all_state_event/2 傳送的事件時,就會調用此函式來處理事件。

StateNamegen_fsm 程序目前的狀態名稱

如需其他引數和可能傳回值的說明,請參閱 Module:StateName/2

連結到此回呼

handle_info(Info, StateName, StateData)

檢視原始碼 (選用)
此回呼已棄用。回呼 gen_fsm:handle_info(_,_,_) 已棄用;請改用 'gen_statem' 模組。
-callback handle_info(Info, StateName, StateData) -> Result
                         when
                             Info :: term(),
                             StateName :: atom(),
                             StateData :: term(),
                             Result ::
                                 {next_state, NextStateName, NewStateData} |
                                 {next_state, NextStateName, NewStateData, Timeout} |
                                 {next_state, NextStateName, NewStateData, hibernate} |
                                 {stop, Reason, NewStateData},
                             NextStateName :: atom(),
                             NewStateData :: term(),
                             Timeout :: timeout(),
                             Reason :: normal | term().

處理傳入的訊息

gen_fsm 程序收到任何非同步或非同步事件(或系統訊息)的其他訊息時,就會調用此函式。

Info 是收到的訊息。

如需其他引數和可能傳回值的說明,請參閱 Module:StateName/2

連結到此回呼

handle_sync_event(Event, From, StateName, StateData)

檢視原始碼
此回呼已棄用。回呼 gen_fsm:handle_sync_event(_,_,_,_) 已棄用;請改用 'gen_statem' 模組。
-callback handle_sync_event(Event, From, StateName, StateData) -> Result
                               when
                                   Event :: term(),
                                   From :: from(),
                                   StateName :: atom(),
                                   StateData :: term(),
                                   Result ::
                                       {reply, Reply, NextStateName, NewStateData} |
                                       {reply, Reply, NextStateName, NewStateData, Timeout} |
                                       {reply, Reply, NextStateName, NewStateData, hibernate} |
                                       {next_state, NextStateName, NewStateData} |
                                       {next_state, NextStateName, NewStateData, Timeout} |
                                       {next_state, NextStateName, NewStateData, hibernate} |
                                       {stop, Reason, Reply, NewStateData} |
                                       {stop, Reason, NewStateData},
                                   Reply :: term(),
                                   NextStateName :: atom(),
                                   NewStateData :: term(),
                                   Timeout :: timeout(),
                                   Reason :: term().

處理同步事件。

每當 gen_fsm 程序收到使用 sync_send_all_state_event/2,3 傳送的事件時,就會調用此函式來處理事件。

StateNamegen_fsm 程序目前的狀態名稱

如需其他引數和可能傳回值的說明,請參閱 Module:StateName/3

此回呼已棄用。回呼 gen_fsm:init(_) 已棄用;請改用 'gen_statem' 模組。
-callback init(Args) -> Result
                  when
                      Args :: term(),
                      Result ::
                          {ok, StateName, StateData} |
                          {ok, StateName, StateData, Timeout} |
                          {ok, StateName, StateData, hibernate} |
                          {stop, Reason} |
                          ignore,
                      StateName :: atom(),
                      StateData :: term(),
                      Timeout :: timeout(),
                      Reason :: term().

初始化程序和內部狀態名稱狀態資料

每當使用 start/3,4start_link/3,4 啟動 gen_fsm 程序時,新程序就會調用此函式進行初始化。

Args 是提供給 start 函式的 Args 引數。

如果初始化成功,此函式會傳回 {ok, StateName, StateData}、{ok, StateName, StateData, Timeout} 或 {ok, StateName, StateData, hibernate},其中 StateNamegen_fsm 程序的初始狀態名稱,而 StateData 是初始狀態資料

如果提供了 integer/0 超時值,則除非在 Timeout 毫秒內收到事件或訊息,否則會發生超時。超時由原子 timeout 表示,並由 Module:StateName/2 回呼函式處理。可以使用原子 infinity 來無限期等待,這是預設值。

如果指定了 hibernate 而不是超時值,則程序會在等待下一個訊息到達時進入休眠狀態(透過呼叫 proc_lib:hibernate/3)。

如果初始化失敗,此函式會傳回 {stop, Reason},其中 Reason 是任何詞彙,或者傳回 ignore

連結到此回呼

'StateName'(Event, StateData)

檢視原始碼 (選用)
此回呼已棄用。回呼 gen_fsm:'StateName'(_,_) 已棄用;請改用 'gen_statem' 模組。
-callback 'StateName'(Event, StateData) -> Result
                         when
                             Event :: timeout | term(),
                             StateData :: term(),
                             Result ::
                                 {next_state, NextStateName, NewStateData} |
                                 {next_state, NextStateName, NewStateData, Timeout} |
                                 {next_state, NextStateName, NewStateData, hibernate} |
                                 {stop, Reason, NewStateData},
                             NextStateName :: atom(),
                             NewStateData :: term(),
                             Timeout :: timeout(),
                             Reason :: term().

處理非同步事件。

對於每個可能的狀態名稱,都會有此函式的一個實例。每當 gen_fsm 程序收到使用 send_event/2 傳送的事件時,就會調用此函式的實例,此實例的名稱與目前的狀態名稱 StateName 相同,以處理事件。如果發生超時,也會調用此函式。

如果發生超時,則 Event 為原子 timeout,否則為提供給 send_event/2Event 引數。

StateDatagen_fsm 程序的狀態資料

如果此函式傳回 {next_state, NextStateName, NewStateData}{next_state, NextStateName, NewStateData, Timeout}{next_state, NextStateName, NewStateData, hibernate},則 gen_fsm 程序會繼續執行,目前的[狀態名稱](#state-name)會設定為 NextStateName,並使用可能會更新的[狀態資料](#state-data) NewStateData。如需 Timeouthibernate 的說明,請參閱 [Module:init/1](c:init/1)。如果此函式傳回 {stop ,Reason, NewStateData},則 gen_fsm 程序會呼叫 Module:terminate(Reason, StateName, NewStateData) 並終止。

連結到此回呼

'StateName'(Event, From, StateData)

檢視原始碼 (選用)
此回呼已棄用。回呼 gen_fsm:'StateName'(_,_,_) 已棄用;請改用 'gen_statem' 模組。
-callback 'StateName'(Event, From, StateData) -> Result
                         when
                             Event :: term(),
                             From :: from(),
                             StateData :: term(),
                             Result ::
                                 {reply, Reply, NextStateName, NewStateData} |
                                 {reply, Reply, NextStateName, NewStateData, Timeout} |
                                 {reply, Reply, NextStateName, NewStateData, hibernate} |
                                 {next_state, NextStateName, NewStateData} |
                                 {next_state, NextStateName, NewStateData, Timeout} |
                                 {next_state, NextStateName, NewStateData, hibernate} |
                                 {stop, Reason, Reply, NewStateData} |
                                 {stop, Reason, NewStateData},
                             Reply :: term(),
                             NextStateName :: atom(),
                             NewStateData :: term(),
                             Timeout :: timeout(),
                             Reason :: normal | term().

處理同步事件。

對於每個可能的狀態名稱,此函數都會有一個實例。每當 gen_fsm 處理程序收到使用 sync_send_event/2,3 發送的事件時,會呼叫與目前狀態名稱 StateName 同名的函數實例來處理該事件。

Event 是提供給 sync_send_event/2,3Event 引數。

From 是一個 tuple {Pid, Tag},其中 Pid 是呼叫 sync_send_event/2,3 的處理程序的 pid/0,而 Tag 是一個唯一的標籤。

StateDatagen_fsm 程序的狀態資料

  • 如果傳回 {reply, Reply, NextStateName, NewStateData}{reply, Reply, NextStateName, NewStateData, Timeout}{reply, Reply, NextStateName, NewStateData, hibernate},則會將 Reply 作為 sync_send_event/2,3 的傳回值傳回給 From。然後,gen_fsm 處理程序會繼續執行,目前的狀態名稱設定為 NextStateName,並且使用可能已更新的 狀態資料 NewStateDataTimeouthibernate 的說明,請參閱 Module:init/1

  • 如果傳回 {next_state, NextStateName, NewStateData}{next_state, NextStateName, NewStateData, Timeout}{next_state, NextStateName, NewStateData, hibernate},則 gen_fsm 處理程序會以 NewStateData 繼續在 NextStateName 中執行。任何對 From 的回覆都必須使用 reply/2 明確指定。

  • 如果函數傳回 {stop, Reason, Reply, NewStateData},則會將 Reply 傳回給 From。如果函數傳回 {stop, Reason, NewStateData},則任何對 From 的回覆都必須使用 reply/2 明確指定。然後,gen_fsm 處理程序會呼叫 Module:terminate(Reason, StateName, NewStateData) 並終止。

連結到此回呼

terminate(Reason, StateName, StateData)

檢視原始碼 (可選)
此回呼已過時。回呼 gen_fsm:terminate(_,_,_) 已過時;請改用 'gen_statem' 模組。
-callback terminate(Reason, StateName, StateData) -> _
                       when
                           Reason :: normal | shutdown | {shutdown, term()} | term(),
                           StateName :: atom(),
                           StateData :: term().

在終止之前清除。

gen_fsm 處理程序即將終止時,會呼叫此函數。它與 Module:init/1 相反,並且執行任何必要的清理。當它傳回時,gen_fsm 處理程序會以 Reason 終止。傳回值會被忽略。

Reason 是一個表示停止原因的詞彙,StateName 是目前的狀態名稱,而 StateDatagen_fsm 處理程序的 狀態資料

Reason 取決於 gen_fsm 處理程序終止的原因。如果因為另一個回呼函數已傳回一個停止 tuple {stop, ...},則 Reason 的值為該 tuple 中指定的值。如果因為失敗,則 Reason 是錯誤原因。

如果 gen_fsm 處理程序是監管樹的一部分,並且由其監管者命令終止,則在以下條件適用時,會使用 Reason = shutdown 呼叫此函數

  • 已將 gen_fsm 處理程序設定為捕獲退出訊號。

  • 在監管者的子系規格中定義的關機策略是一個整數逾時值,而不是 brutal_kill。

即使 gen_fsm 處理程序不是監管樹的一部分,如果它從其父系收到 'EXIT' 訊息,也會呼叫此函數。Reason'EXIT' 訊息中的相同。

否則,gen_fsm 處理程序會立即終止。

請注意,對於任何 normalshutdown{shutdown, Term} 以外的原因,gen_fsm 處理程序都假設為因錯誤而終止,並使用 error_logger:format/2 發出錯誤報告。

函數

此函數已過時。gen_fsm:cancel_timer/1 已過時;請改用 'gen_statem' 模組。
-spec cancel_timer(Ref) -> RemainingTime | false
                      when Ref :: reference(), RemainingTime :: non_neg_integer().

取消通用 FSM 中的內部計時器。

取消在此函數呼叫的 gen_fsm 處理程序中由 Ref 參照的內部計時器。

Ref 是從 send_event_after/2start_timer/2 傳回的參考。

如果計時器已逾時,但事件尚未傳遞,則會取消該事件,如同它未逾時一樣,因此從此函數傳回後,不會有錯誤的計時器事件。

如果 Ref 參照的是活動計時器,則傳回計時器過期前剩餘的毫秒數,否則傳回 false

連結至此函數

enter_loop(Module, Options, StateName, StateData)

檢視原始碼
此函數已過時。gen_fsm:enter_loop/4 已過時;請改用 'gen_statem' 模組。
-spec enter_loop(Module, Options, StateName, StateData) -> no_return()
                    when
                        Module :: module(),
                        Options :: [enter_loop_opt()],
                        StateName :: atom(),
                        StateData :: term().

進入 gen_fsm 接收迴圈。

等同於具有 Timeout = infinityenter_loop/6,但已啟動的伺服器不會像 start_link/3 一樣註冊。

此函數已過時。gen_fsm:enter_loop/5 已過時;請改用 'gen_statem' 模組。
-spec enter_loop(Module, Options, StateName, StateData, FsmName) -> no_return()
                    when
                        Module :: module(),
                        Options :: [enter_loop_opt()],
                        StateName :: atom(),
                        StateData :: term(),
                        FsmName :: fsm_name();
                (Module, Options, StateName, StateData, Timeout) -> no_return()
                    when
                        Module :: module(),
                        Options :: enter_loop_opt(),
                        StateName :: atom(),
                        StateData :: term(),
                        Timeout :: timeout().

進入 gen_fsm 接收迴圈。

使用引數 FsmName 等同於具有 Timeout = infinityenter_loop/6

使用引數 Timeout 等同於 enter_loop/6,但已啟動的伺服器不會像 start_link/3 一樣註冊。

連結至此函數

enter_loop(Module, Options, StateName, StateData, FsmName, Timeout)

檢視原始碼
此函數已過時。gen_fsm:enter_loop/6 已過時;請改用 'gen_statem' 模組。
-spec enter_loop(Module, Options, StateName, StateData, FsmName, Timeout) -> no_return()
                    when
                        Module :: module(),
                        Options :: [enter_loop_opt()],
                        StateName :: atom(),
                        StateData :: term(),
                        FsmName :: fsm_name() | pid(),
                        Timeout :: timeout().

進入 gen_fsm 接收迴圈。

將現有的處理程序轉換為 gen_fsm 處理程序。不會傳回,而是呼叫處理程序進入 gen_fsm 接收迴圈,並成為 gen_fsm 處理程序。處理程序必須使用 proc_lib 中的其中一個開始函數啟動。使用者負責處理程序的任何初始化,包括註冊其名稱。

當需要比 gen_fsm 行為提供的更複雜的初始化程序時,此函數很有用。

ModuleOptionsFsmName 的含義與呼叫 start[_link]/3,4 時的含義相同。但是,必須先根據 FsmName 註冊處理程序,然後才能呼叫此函數。

StateNameStateDataTimeout 的含義與 Module:init/1 的傳回值中的含義相同。回呼模組 Module 不需要匯出 init/1 函數。

如果呼叫處理程序不是由 proc_lib 開始函數啟動,或者未根據 FsmName 註冊,則此函數將失敗。

此函數已過時。gen_fsm:reply/2 已過時;請改用 'gen_statem' 模組。
-spec reply(Caller, Reply) -> Result when Caller :: from(), Reply :: term(), Result :: term().

向呼叫者傳送回覆。

當無法在 Module:StateName/3Module:handle_sync_event/4 的傳回值中定義回覆時,gen_fsm 處理程序可以使用此函數,明確地將回覆傳送給呼叫 sync_send_event/2,3sync_send_all_state_event/2,3 的用戶端處理程序。

Caller 必須是提供給回呼函數的 From 引數。Reply 是作為 sync_send_event/2,3sync_send_all_state_event/2,3 的傳回值傳回給用戶端的任何詞彙。

傳回值 Result 沒有進一步定義,且永遠應忽略。

連結至此函數

send_all_state_event(FsmRef, Event)

檢視原始碼
此函數已過時。gen_fsm:send_all_state_event/2 已過時;請改用 'gen_statem' 模組。
-spec send_all_state_event(FsmRef, Event) -> ok when FsmRef :: fsm_ref(), Event :: term().

將事件非同步傳送至通用 FSM。

將事件以非同步方式傳送至 gen_fsm 處理程序的 FsmRef,並立即傳回 okgen_fsm 處理程序會呼叫 Module:handle_event/3 來處理事件。

如需引數的說明,請參閱 send_event/2

send_event/2send_all_state_event/2 的區別在於使用哪個回呼函數來處理事件。當傳送在每個狀態中以相同方式處理的事件時,此函數很有用,因為只需要一個 handle_event 子句來處理事件,而不是在每個狀態名稱函數中都有一個子句。

連結至此函數

send_event(FsmRef, Event)

檢視原始碼
此函數已過時。gen_fsm:send_event/2 已過時;請改用 'gen_statem' 模組。
-spec send_event(FsmRef, Event) -> ok when FsmRef :: fsm_ref(), Event :: term().

將事件非同步傳送至通用 FSM。

Event 傳送至 gen_fsm 處理程序的 FsmRef,並立即傳回 okgen_fsm 處理程序會呼叫 Module:StateName/2 來處理事件,其中 StateNamegen_fsm 處理程序目前狀態的名稱。

FsmRef 可以是下列任一項

  • pid/0
  • Name,如果 gen_fsm 處理程序在本機註冊
  • {Name, Node},如果 gen_fsm 處理程序在另一個節點上本機註冊
  • {global, GlobalName},如果 gen_fsm 處理程序為全域註冊
  • {via, Module, ViaName},如果 gen_fsm 處理程序透過替代處理程序登錄來註冊

Event 是作為 Module:StateName/2 的其中一個引數傳遞的任何詞彙。

連結至此函數

send_event_after(Time, Event)

檢視原始碼
此函數已過時。gen_fsm:send_event_after/2 已過時;請改用 'gen_statem' 模組。
-spec send_event_after(Time, Event) -> Ref
                          when Time :: non_neg_integer(), Event :: term(), Ref :: reference().

在通用 FSM 中延遲傳送內部事件。

在此函數呼叫的 gen_fsm 處理程序中,在 Time 毫秒後,以內部方式傳送延遲事件。立即傳回一個參考,可用於使用 cancel_timer/1 取消延遲傳送。

gen_fsm 處理程序會呼叫 Module:StateName/2 來處理事件,其中 'StateName' 是在傳遞延遲事件時,gen_fsm 處理程序目前狀態的名稱。

Event 是作為 Module:StateName/2 的其中一個引數傳遞的任何詞彙。

連結至此函數

start(Module, Args, Options)

檢視原始碼
此函數已過時。gen_fsm:start/3 已過時;請改用 'gen_statem' 模組。
-spec start(Module, Args, Options) -> Result
               when
                   Module :: module(),
                   Args :: term(),
                   Options :: [start_opt()],
                   Result :: {ok, Pid} | ignore | {error, Reason},
                   Pid :: pid(),
                   Reason :: term().

建立未註冊的獨立 gen_fsm 程序。

等同於 start(Name, Mod, Args, Options),而不註冊 Name

如需引數和傳回值的說明,請參閱 start_link/3,4

連結至此函數

start(FsmName, Module, Args, Options)

檢視原始碼
此函式已過時。gen_fsm:start/4 已過時;請改用 'gen_statem' 模組。
-spec start(FsmName, Module, Args, Options) -> Result
               when
                   FsmName :: fsm_name(),
                   Module :: module(),
                   Args :: term(),
                   Options :: [start_opt()],
                   Result :: {ok, Pid} | ignore | {error, Reason},
                   Pid :: pid(),
                   Reason :: {already_started, Pid} | term().

建立獨立的 gen_fsm 程序。

建立的程序不屬於監督樹的一部分,因此沒有監督者。

有關引數和回傳值的說明,請參閱 start_link/3,4

連結至此函數

start_link(Module, Args, Options)

檢視原始碼
此函式已過時。gen_fsm:start_link/3 已過時;請改用 'gen_statem' 模組。
-spec start_link(Module, Args, Options) -> Result
                    when
                        Module :: module(),
                        Args :: term(),
                        Options :: [start_opt()],
                        Result :: {ok, Pid} | ignore | {error, Reason},
                        Pid :: pid(),
                        Reason :: term().

在監督樹中建立未註冊的 gen_fsm 程序。

等同於 start_link(Name, Mod, Args, Options),但不註冊 Name

連結至此函數

start_link(FsmName, Module, Args, Options)

檢視原始碼
此函式已過時。gen_fsm:start_link/4 已過時;請改用 'gen_statem' 模組。
-spec start_link(FsmName, Module, Args, Options) -> Result
                    when
                        FsmName :: fsm_name(),
                        Module :: module(),
                        Args :: term(),
                        Options :: [start_opt()],
                        Result :: {ok, Pid} | ignore | {error, Reason},
                        Pid :: pid(),
                        Reason :: {already_started, Pid} | term().

在監督樹中建立 gen_fsm 程序。

此程序是作為監督樹的一部分建立。此函式應由監督者直接或間接呼叫。例如,它確保 gen_fsm 程序連結到監督者。

gen_fsm 程序會呼叫 Module:init/1 進行初始化。為了確保同步啟動程序,start_link/3,4 會在 Module:init/1 回傳後才回傳。

  • 如果 FsmName = {local, Name}gen_fsm 程序會使用 register/2 在本機註冊為 Name

  • 如果 FsmName = {global, GlobalName}gen_fsm 程序會使用 global:register_name/2 全域註冊為 GlobalName

  • 如果 FsmName = {via, Module, ViaName}gen_fsm 程序會向 Module 代表的註冊表註冊。Module 回呼應匯出函式 register_name/2unregister_name/1whereis_name/1send/2,這些函式的行為應與 global 中的對應函式類似。因此,{via, global, GlobalName} 是一個有效的參照。

Module 是回呼模組的名稱。

Args 是傳遞為 Module:init/1 引數的任何 term。

如果存在選項 {timeout, Time},則允許 gen_fsm 程序花費 Time 毫秒進行初始化,否則它會終止且啟動函式會回傳 {error, timeout}

如果存在選項 {debug, Dbgs},則會針對 Dbgs 中的每個項目呼叫對應的 sys 函式;請參閱 sys(3)

如果存在選項 {spawn_opt, SOpts},則會將 SOpts 作為選項列表傳遞給用於產生 gen_fsm 程序的 spawn_opt BIF;請參閱 spawn_opt/2

注意

不允許使用產生選項 monitor,這會導致函式因 badarg 原因而失敗。

如果成功建立並初始化 gen_fsm 程序,則函式會回傳 {ok, Pid},其中 Pidgen_fsm 程序的 pid。如果已存在具有指定 FsmName 的程序,則函式會回傳 {error, {already_started, Pid}},其中 Pid 是該程序的 pid。

如果 Module:init/1Reason 而失敗,則函式會回傳 {error, Reason}。如果 Module:init/1 回傳 {stop, Reason}ignore,則程序會終止,且函式會分別回傳 {error, Reason}ignore

連結至此函數

start_timer(Time, Msg)

檢視原始碼
此函式已過時。gen_fsm:start_timer/2 已過時;請改用 'gen_statem' 模組。
-spec start_timer(Time, Msg) -> Ref when Time :: non_neg_integer(), Msg :: term(), Ref :: reference().

在通用 FSM 中內部傳送逾時事件。

在呼叫此函式的 gen_fsm 程序中,在 Time 毫秒後,會在內部傳送逾時事件。立即回傳一個參考,該參考可用於使用 cancel_timer/1 取消計時器。

gen_fsm 程序會呼叫 Module:StateName/2 來處理事件,其中 'StateName' 是傳遞逾時訊息時 gen_fsm 程序的目前狀態名稱。

Msg 是任何傳遞到逾時訊息 {timeout, Ref, Msg} 中的 term,作為 Module:StateName/2 的引數之一。

此函式已過時。gen_fsm:stop/1 已過時;請改用 'gen_statem' 模組。
-spec stop(FsmRef) -> ok when FsmRef :: fsm_ref().

等同於 stop(FsmRef, normal, infinity)

連結至此函數

stop(FsmRef, Reason, Timeout)

檢視原始碼
此函式已過時。gen_fsm:stop/3 已過時;請改用 'gen_statem' 模組。
-spec stop(FsmRef, Reason, Timeout) -> ok
              when FsmRef :: fsm_ref(), Reason :: term(), Timeout :: timeout().

同步停止通用 FSM。

命令泛型有限狀態機以指定的 Reason 結束,並等待其終止。gen_fsm 程序會在結束前呼叫 Module:terminate/3

如果泛型有限狀態機以預期的原因終止,則函式會回傳 ok。任何其他原因(而非 normalshutdown{shutdown, Term})都會使用 error_logger:format/2 發出錯誤報告。

Timeout 是一個大於零的整數,指定等待泛型 FSM 終止的毫秒數,或是原子 infinity 以無限期等待。如果泛型有限狀態機未在指定的時間內終止,則會引發 timeout 例外。

如果程序不存在,則會引發 noproc 例外。

連結至此函數

sync_send_all_state_event(FsmRef, Event)

檢視原始碼
此函式已過時。gen_fsm:sync_send_all_state_event/2 已過時;請改用 'gen_statem' 模組。
-spec sync_send_all_state_event(FsmRef, Event) -> Reply
                                   when FsmRef :: fsm_ref(), Event :: term, Reply :: term().

等同於 sync_send_all_state_event(FsmRef, Event, 5000)

連結至此函數

sync_send_all_state_event(FsmRef, Event, Timeout)

檢視原始碼
此函式已過時。gen_fsm:sync_send_all_state_event/3 已過時;請改用 'gen_statem' 模組。
-spec sync_send_all_state_event(FsmRef, Event, Timeout) -> Reply
                                   when
                                       FsmRef :: fsm_ref(),
                                       Event :: term(),
                                       Timeout :: timeout(),
                                       Reply :: term().

將事件同步傳送至通用 FSM。

將事件傳送至 gen_fsm 程序的 FsmRef,並等待直到收到回覆或發生逾時。gen_fsm 程序會呼叫 Module:handle_sync_event/4 來處理事件。

有關 FsmRefEvent 的說明,請參閱 send_event/2。有關 TimeoutReply 的說明,請參閱 sync_send_event/3

有關 sync_send_eventsync_send_all_state_event 之間差異的討論,請參閱 send_all_state_event/2

連結至此函數

sync_send_event(FsmRef, Event)

檢視原始碼
此函式已過時。gen_fsm:sync_send_event/2 已過時;請改用 'gen_statem' 模組。
-spec sync_send_event(FsmRef, Event) -> Reply when FsmRef :: fsm_ref(), Event :: term(), Reply :: term().

等同於 sync_send_event(FsmRef, Event, 5000)

連結至此函數

sync_send_event(FsmRef, Event, Timeout)

檢視原始碼
此函式已過時。gen_fsm:sync_send_event/3 已過時;請改用 'gen_statem' 模組。
-spec sync_send_event(FsmRef, Event, Timeout) -> Reply
                         when
                             FsmRef :: fsm_ref(), Event :: term(), Timeout :: timeout(), Reply :: term().

將事件同步傳送至通用 FSM。

將事件傳送至 gen_fsm 程序的 FsmRef,並等待直到收到回覆或發生逾時。gen_fsm 程序會呼叫 Module:StateName/3 來處理事件,其中 'StateName'gen_fsm 程序的目前狀態名稱。

有關 FsmRefEvent 的說明,請參閱 send_event/2

Timeout 是一個大於零的整數,指定等待回覆的毫秒數,或是原子 infinity 以無限期等待。如果在指定的時間內沒有收到回覆,則函式呼叫會失敗。

回傳值 Reply 定義於 Module:StateName/3 的回傳值中

注意

如果在 Erlang 5.6/OTP R12B 中,當伺服器在連結到用戶端的呼叫期間死亡時,有時會取用伺服器結束訊息的舊行為已移除。