文档章节

gen_fsm

光风霁月
 光风霁月
发布于 2014/06/05 14:06
字数 710
阅读 72
收藏 0

    有限状态机(问什么从来没有提过无限状态机,请知道的朋友不吝赐教)的官方文档定义是:

State(S) x Event(E) -> Actions(A), State(S')

If we are in state S and the event E occurs, we should perform the actions A and make a transition to        the state S'.

  或者用下面的表理解:

条件/当前状态
状态A
状态B
状态C
条件X
...
...
...
条件Y
...
状态C
...
条件Z
状态B
...
状态A

 如何写一个gen_fms呢,下面以例子来讲诉。

 1. 假设一个人有这么3种状态(健康,生病和康复中),以及对应的转换事件(淋雨,治疗和休息)

  2. 定义状态名分别为health,sick和rehabilitationing,事件分别为rain,treatment和一个特殊的timeout。每种状态下,不需要额外的状态数据。

  3. 按照gen_fsm规定,状态转换规则是以状态名同名的回调函数,格式为:

StateName(Event, StateData) ->
    .. code for actions here ...
    {next_state, StateName', StateData'}

  所以在这个例子里,我们写上3个状态处理回调函数:

%% 健康状态下淋雨,变为生病状态
health( rain, StateData ) ->
    { next_state, sick, StateData }.

%% 生病状态下被治疗,进入康复中状态    
sick( treatment, StateData ) ->
    { next_state, rehabilitationing, StateData, 30000  }.      %% 30秒后有timeout事件

%% 康复中状态下,超时事件发生,进入健康状态
rehabilitationing( timeout, StateData ) ->
    { next_state, health, StateData }.

  每个状态处理回调函数的返回值必须是{next_state, 新状态名,新状态对应的状态数据},或者{next_state, 新状态名,新状态对应的状态数据, Timeout时间}。(还可以用{stop, Reason, StateData}作为返回值,来告知gem_fsm进程结束)

  4. 我们还需要一个初始状态,在init回调设置初始状态

init(_Param) ->
  {ok, health, {} }.

  5. 为模块写事件触发API,用gen_fsm:send_event通知gen_fsm事件发生(事件不一定是atom,可以是任意的erlang类型)。

rain() ->
    gen_fsm:send_event( ?MODULE, rain ).

treatment() ->
    gen_fsm:send_event( ?MODULE, treatment  ).

6. 加上启动API和指定行为模式,我们的gen_fsm例子就算大功告成了。全模块代码如下:

-module(person_fsm).
-behaviour(gen_fsm).

-export([start_link/0, init/1]).
-export([rain/0, treatment/0]).
-export([health/2,sick/2,rehabilitationing/2]).

start_link() ->
    gen_fsm:start_link( {local,?MODULE}, ?MODULE, [], [] ).

init([]) ->
    io:format("initial state is health.~n"),
    {ok, health, {} }.

rain() ->
    gen_fsm:send_event( ?MODULE, rain ).

treatment() ->
    gen_fsm:send_event( ?MODULE, treatment  ).

%% finite state machines
health( rain, {} ) ->
    io:format("turn to state sick.~n"),
    { next_state, sick, {} }.
    
sick( treatment, _StateData ) ->
    io:format("turn to state rehabilitationing.~n"),
    { next_state, rehabilitationing, { }, 30000  }.

rehabilitationing( timeout, _StateData ) ->
    io:format("turn to state health.~n"),
    { next_state, health, {} }.

  gen_fsm:start_link在此不细讲了,如果不清楚的参见原官方文档。  


gen_server和gen_fsm比较:

1. gen_server的状态对应为gen_fsm的一个状态名和状态数据。

2. gen_server在handle_cast里处理异步消息/事件,gen_fsm在状态名同名的回调处理异步事件。

3. gen_fsm实现的例子完全可以用gen_server来实现。


© 著作权归作者所有

共有 人打赏支持
上一篇: vi用法和配置
下一篇: erlang的dict用法
光风霁月
粉丝 9
博文 12
码字总数 7051
作品 0
闵行
程序员
私信 提问
erlang:hibernate/3函数的使用案例

参考rabbitmq代码的使用情况:

格通
2016/08/19
5
0
用rebar来构建,编译,测试,发布Erlang应用程序

rebar是一个遵循Erlang/OTP原则的Erlang项目构建工具,使用它可以减少构建标准Erlang/OTP项目架构配置的工作量,并且可以很容易的编译,测试,发布Erlang应用程序。更强大的是,rebar提供了一...

nao
2015/06/10
0
0
[Erlang 0015]Erlang OTP设计原则

阅读Erlang官方文档经常可以读到下面两句: "xxx implemented using this module will have a standard set of interface functions and include functionality for tracing and error report......

唐玄奘
2017/12/03
0
0
erlang]supervisor(监控树)的重启策略

1. init函数 Id 子进程ID标识符 StartFunc = {M, F, A}: 子程序启动入口 Restart: 重启方案 : 如果app终止了,整个系统都会停止工作(application:stop/1除外)。 : 如果app以normal的原因终...

技术小牛人
2017/11/22
0
0
用 rebar 来构建、编译、测试、发布 Erlang 应用程序

rebar 是一个遵循 Erlang/OTP 原则的 Erlang 项目构建工具,使用它可以减少构建标准 Erlang/OTP 项目架构配置的工作量,并且可以很容易的编译、测试、发布 Erlang 应用程序。更强大的是,reb...

千山万水
2015/10/15
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

听说拼多多因漏洞被薅了200亿?- 谈谈软件测试

昨天看到一个大新闻:拼多多在20日凌晨出现漏洞,用户可以领100元无门槛优惠券。一夜之间,被黑产、羊毛党和闻讯而来的吃瓜群众薅了个底朝天,直到第二天上午9点才将优惠券下架。网上传言这一...

crossin
25分钟前
2
0
微服务架构有毒,何时不使用微服务?

在过去的四年中,使用微服务来构建应用程序似乎成了一种标准。大多数我所合作过的团队也对此表现出了不同程度的兴趣。 微服务所承诺的弹性、高可用、低耦合、敏捷,以及能够解决单体架构带来...

架构师springboot
30分钟前
2
0
日志服务Python消费组实战(三):实时跨域监测多日志库数据

摘要: 本文主要介绍如何使用消费组实时监控多个域中的多个日志库中的异常数据,并进行下一步告警动作。具备配置简单、逻辑灵活、支持跨域多Region、实时监测,无需配置索引等特点,并且性能...

阿里云云栖社区
31分钟前
2
0
常用css动效

1.列表浮层变化动效 demo地址 下载地址 2.js动画库 github地址 3.滚动加载 Scrollreveal 4.其他动效 tobiasahlin

chinahufei
32分钟前
2
0
Coding and Paper Letter(四十六)

资源整理。 1 Coding: 1.卫星影像深度学习资源。 satellite image deep learning 2.runoff tools为MOM生成径流文件的一些工具变得轻而易举。 runoff tools 3.NOAA-GFDL海冰模拟器V2.0。 SIS2...

胖胖雕
34分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部