erlang四大behaviour之二
阿新 • • 發佈:2018-12-12
今天介紹erlang的一個非常重要的behaviour,就是gen_fsm-有限狀態機,有限狀態機的作用非常之多,比如文字解析,模式匹配、 遊戲邏輯等等方面的處理都是它的強項,所以這個behaviour非常之重要
表示的就是在S狀態時如果有事件E發生,那麼執行動作A後把狀態調整到S’。
對於一個用gen_fsm行為實現的狀態機來說,狀態轉變規則被寫為符合如下規定的一系列Erlang函式:
StateName( Event, StateData ) ->
.. code for actions here …
{ next_state, StateName’, StateData’ }
erlang手冊中用這個例子來解釋的:開鎖問題,有一個密碼鎖的門,它就可以看作一個狀態機,初始狀態門是鎖著的,任何時候有人按一個密碼鍵就會 產生一個事件,這個鍵值和前面的按鍵組合後與密碼相比較,看是否正確,如果輸入的密碼順序是對的,那麼將門開啟30秒,如果輸入密碼不完全,則等待下次按 鈕按下,如果輸入密碼順序是錯的,則重新開始等待按鍵按下。
1. 有限狀態機
有限狀態機可以用下面這個公式來表達1 | <span style="font-family: Arial;" |
2. 一個例子
erlang手冊中用這個例子來解釋的:開鎖問題,有一個密碼鎖的門,它就可以看作一個狀態機,初始狀態門是鎖著的,任何時候有人按一個密碼鍵就會 產生一個事件,這個鍵值和前面的按鍵組合後與密碼相比較,看是否正確,如果輸入的密碼順序是對的,那麼將門開啟30秒,如果輸入密碼不完全,則等待下次按 鈕按下,如果輸入密碼順序是錯的,則重新開始等待按鍵按下。
123456789101112131415161718192021222324 | <span style="color: rgb(1, 78, 164);">-</span><span style="color: rgb(84, 0, 179);">module</span><span style="color: rgb(16, 154, 184);">(</span>code_lock<span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(1, 78, 164);">-</span><span style="color: rgb(84, 0, 179);">behaviour</span><span style="color: rgb(16, 154, 184);">(</span>gen_fsm<span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(1, 78, 164);">-</span><span style="color: rgb(84, 0, 179);">export</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(16, 154, 184);">[</span>start_link<span style="color: rgb(1, 78, 164);">/</span><span style="color: rgb(255, 150, 0);">1</span><span style="color: rgb(16, 154, 184);">]</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(1, 78, 164);">-</span><span style="color: rgb(84, 0, 179);">export</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(16, 154, 184);">[</span>button<span style="color: rgb(1, 78, 164);">/</span><span style="color: rgb(255, 150, 0);">1</span><span style="color: rgb(16, 154, 184);">]</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(1, 78, 164);">-</span><span style="color: rgb(84, 0, 179);">export</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(16, 154, 184);">[</span>init<span style="color: rgb(1, 78, 164);">/</span><span style="color: rgb(255, 150, 0);">1</span><span style="color: rgb(107, 184, 16);">,</span> locked<span style="color: rgb(1, 78, 164);">/</span><span style="color: rgb(255, 150, 0);">2</span><span style="color: rgb(107, 184, 16);">,</span> open<span style="color: rgb(1, 78, 164);">/</span><span style="color: rgb(255, 150, 0);">2</span><span style="color: rgb(16, 154, 184);">]</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(255, 60, 0);">start_link</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">-></span><span style="color: rgb(255, 78, 24);">gen_fsm</span>:<span style="color: rgb(255, 60, 0);">start_link</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(16, 154, 184);">{</span>local<span style="color: rgb(107, 184, 16);">,</span> code_lock<span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(107, 184, 16);">,</span> code_lock<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">[</span><span style="color: rgb(16, 154, 184);">]</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(255, 60, 0);">button</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(69, 179, 230);">Digit</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">-></span><span style="color: rgb(255, 78, 24);">gen_fsm</span>:<span style="color: rgb(255, 60, 0);">send_event</span><span style="color: rgb(16, 154, 184);">(</span>code_lock<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">{</span>button<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(69, 179, 230);">Digit</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(255, 60, 0);">init</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">-></span><span style="color: rgb(16, 154, 184);">{</span>ok<span style="color: rgb(107, 184, 16);">,</span> locked<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">{</span><span style="color: rgb(16, 154, 184);">[</span><span style="color: rgb(16, 154, 184);">]</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(107, 184, 16);">.</span><span style="color: rgb(255, 60, 0);">locked</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(16, 154, 184);">{</span>button<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(69, 179, 230);">Digit</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">{</span><span style="color: rgb(69, 179, 230);">SoFar</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">-></span><span style="color: rgb(24, 104, 149);">case</span><span style="color: rgb(16, 154, 184);">[</span><span style="color: rgb(69, 179, 230);">Digit</span>|SoFar<span style="color: rgb(16, 154, 184);">]</span><span style="color: rgb(24, 104, 149);">of</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(107, 184, 16);">-></span><span style="color: rgb(255, 60, 0);">do_unlock</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">{</span>next_state<span style="color: rgb(107, 184, 16);">,</span> open<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">{</span><span style="color: rgb(16, 154, 184);">[</span><span style="color: rgb(16, 154, 184);">]</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(255, 150, 0);">3000</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(107, 184, 16);">;</span><span style="color: rgb(69, 179, 230);">Incomplete</span><span style="color: rgb(24, 104, 149);">when</span><span style="color: rgb(255, 60, 0);">length</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(69, 179, 230);">Incomplete</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(1, 78, 164);"><</span><span style="color: rgb(255, 60, 0);">length</span><span style="color: rgb(16, 154, 184);">(</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(16, 154, 184);">)</span><span style="color: rgb(107, 184, 16);">-></span><span style="color: rgb(16, 154, 184);">{</span>next_state<span style="color: rgb(107, 184, 16);">,</span> locked<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">{</span><span style="color: rgb(69, 179, 230);">Incomplete</span><span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(69, 179, 230);">Code</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(16, 154, 184);">}</span><span style="color: rgb(107, 184, 16);">;</span><span style="color: rgb(69, 179, 230);">_Wrong</span><span style="color: rgb(107, 184, 16);">-></span><span style="color: rgb(16, 154, 184);">{</span>next_state<span style="color: rgb(107, 184, 16);">,</span> locked<span style="color: rgb(107, 184, 16);">,</span><span style="color: rgb(16, 154, 184);">{</span><span style="color: rgb(16, 154, 184);">[</span><span style=< |