OTP Design Principles: Gen_Fsm Behaviour
6496 단어 UP
1, 제한된 상태기
FSM, FSM 은 다음과 같은 형식으로 관계 집합을 설명할 수 있습니다.
State(S) x Event(E) -> Actions(A), State(S')
만약에 우리가 상태 S에 있고 이벤트 E가 보내면 우리는 동작 A를 실행하고 상태를 S로 바꿔야 한다는 뜻이다.
2, 예
코드 자물쇠가 있는 문, 입력한 코드 순서가 맞다면 30초 동안 문을 열어라
입력 코드가 완전하지 않으면 다음 단추를 기다리고, 입력 코드의 순서가 틀리면 다시 대기 단추를 누르기 시작합니다
-module(code_lock).
-behaviour(gen_fsm).
-export([start_link/1]).
-export([button/1]).
-export([init/1, locked/2, open/2]).
start_link(Code) ->
gen_fsm:start_link({local, code_lock}, code_lock, Code, []).
button(Digit) ->
gen_fsm:send_event(code_lock, {button, Digit}).
init(Code) ->
{ok, locked, {[], Code}}.
locked({button, Digit}, {SoFar, Code}) ->
case [Digit|SoFar] of
Code ->
do_unlock(),
{next_state, open, {[], Code}, 3000};
Incomplete when length(Incomplete) < length(Code) ->
{next_state, locked, {Incomplete, Code}};
_Wrong ->
{next)state, locked, {[], Code}};
end.
open(timeout, State) ->
do_lock(),
{next_state, locked, State}.
3, Gen 시작Fsm
위의 예에서 코드 사용lock:start_링크 시작genfsm:
start_link(Code) ->
gen_fsm:start_link({locak, code_lock}, code_lock, Code, []).
start_link 호출genfsm:start_link/4, 새gen 시작fsm 프로세스 및 연결
1) 첫 번째 매개변수 {local, code lock} 이름을 지정하고 로컬에서 code 로 등록lock
2) 두 번째 매개변수 codelock 실행 콜백 모듈
3) 세 번째 매개 변수 코드는 콜백 메소드 init에 전달되는 매개 변수이며, 여기서 init 메소드에서 정확한 코드 잠금을 획득한 코드
4) 네 번째 채택수 []는 options
프로세스 등록이 성공하면 새genfsm 프로세스 호출 콜백 방법 codelock: init(Code), 반환 {ok, StateName, StateData}
StateName은gen 입니다.fsm의 초기 상태, 여기서 되돌아오는 것은locked입니다. 초기 상태에서 문이 잠겨 있음을 나타냅니다.
StateData는 gen 입니다.fsm의 내부 상태입니다.state 데이터는 현재 단추 순서 (처음에는 비어 있음) 와 정확한 잠금 코드입니다.
init(Code) ->
{ok, locked, {[], Code}}.
주의genfsm:start_link는gen 까지 동기화됨fsm 프로세스가 초기화되고 요청을 받을 준비가 되었을 때 되돌아옵니다
gen_fsm:start_link는 Supervisor,genfsm:start는 단독gen 을 시작합니다fsm 프로세스
4, 이벤트 알림
gen 사용fsm:send_이벤트/2로 단추 이벤트 알림:
button(Digit) ->
gen_fsm:send_event(code_lock, {button, Digit}).
code_lock은genfsm 프로세스의 이름, {button, Digit}은 실제 이벤트입니다.
이벤트는gen 에게 메시지로 전송됩니다fsm 프로세스, 이벤트 수신 후,genfsm에서 StateName(Event, StateData)을 호출하고 {next state, StateName1, StateData1} 반환
StateName은 현재 상태의 이름이고, StateName1은 다음 상태가 될 상태의 이름이며, StateData1은gen 입니다.fsm의 새 state data 값:
locked({button, Digit}, {SoFar, Code}) ->
case [Digit|SoFar] of
Code ->
do_unlock(),
{next_state, open, {[], Code}, 3000};
Incomplete when length(Incomplete) < length(Code) ->
{next_state, locked, {Incomplete, Code}};
_Wrong ->
{next_state, locked, {[], Code}};
end.
open(timeout, State) ->
do_lock(),
{next_state, locked, State}.
만약 문이 잠겨 있다면, 이때 단추를 누르면 현재 단추의 순서와 정확한 코드 순서를 비교하고, 비교 결과에 따라 unlock문인지 계속locked인지 결정한다
5, 시간 초과
올바른 버튼 순서를 입력하면 문unlock이 다음과 같은 tuple로 돌아갑니다.
{next_state, open, {[], Code}, 30000};
30000은 시간 초과가 30000밀리초이고 30000밀리초 이후에 시간 초과가 발생하면 StateName(timeout, StateData)을 호출합니다.
여기서 문을 30초 동안 열고 다시 잠그세요.
open(timeout, State) ->
do_lock(),
{next_state, locked, State}.
6, 모든 상태 이벤트
때로는 한 사건이gen 에 도달할 수 있다fsm 프로세스의 모든 상태입니다. 이 메시지는gen 을 사용할 수 있습니다.fsm:send_all_state_이벤트/2로 메시지를 보내고 Module:handle이벤트/3 처리
-module(code_lock).
...
-export([stop/0]).
...
stop() ->
gen_fsm:send_all_state_event(code_lock, stop).
...
handle_event(stop, _StateName, StateData) ->
{stop, normal, StateData}.
7, 중지
7.1 Supervision Tree에서
하면, 만약, 만약...fsm는 Supervision tree에서 stop 방법이 필요 없음,genfsm가 자동으로 슈퍼바이저에 의해 정지됨
종료하기 전에 데이터를 정리해야 한다면 shutdown strategy는timeout이고gen 이어야 합니다fsm의 init 방법에서 exit 신호를 포획하고
gen_fsm 프로세스는 콜백 방법terminate(shutdown, StateName, StateData)를 호출합니다.
init(Args) ->
...,
process_flag(trap_exit, true),
...,
{ok, Statename, StateData}.
...
terminate(shutdown, StateName, StateData} ->
..code for cleaning up here..
ok.
7.2 단독 GenFsms 프로세스
하면, 만약, 만약...fsm 프로세스에 supervisor가 없으면 stop 메서드가 필요합니다.
...
-export([stop/0]).
...
stop() ->
gen_fsm:send_all_state_event(code_lock, stop).
...
handle_event(stop, _StateName, StateData) ->
{stop, normal, StateData}.
...
terminate(normal, _StateName, _StateData) ->
ok.
callback 방법은 stop 이벤트를 처리하고 {stop,normal,StateData1}로 되돌려줍니다.normal은 정상 정지를 표시하고 StateData1은gen 입니다fsm의 새 데이터 값
이로 인해genfsm에서terminate(normal,StateName,StateData1)를 호출하고 우아하게 멈추기
8, 기타 메시지 처리
기타 메시지 처리 콜백 방법은handlinfo(Info, StateName, StateData), 예를 들어 다른 비supervisor 프로세스에 연결하고 exit 신호를 포착할 때 exit 메시지를 처리하는 경우:
handle_info({'EXIT', Pid, Reason}, StateName, StateData) ->
..code to handle exits here..
{next_state, StateName1, StateData1}.
보충:genfsm exports and callbacks
gen_fsm module Callback module
gen_fsm:start_link -------------------> Module:init/1
gen_fsm:start
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
gen_fsm:reply
gen_fsm:send_event_after
gen_fsm:start_timer
gen_fsm:cancel_timer
gen_fsm:enter_loop
Module:handle_info/3
Module:terminate/3
Module:code_change/4
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
개인 FLEX 지식 라이브러리 작업 노트[size=large]1、 이 방법은 TileWindows 팝업 창에 있습니다. TitleWindows의 maxWidth와 maxHeight를 지정하지 않으면 최대 값이 화면 전체에 깔립니다. 페이지의minHeigh...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.