有限状态机(Finite-state machine)又称有限状态自动机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。常用与:正则表达式引擎,编译器的词法和语法分析,游戏设计,网络协议,企业应用中等方面。

状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主要是出于对状态机的内在因果关系的考虑。
“现态”和“条件”是因,“动作”和“次态”是果。
1. 现态:是指当前所处的状态。
2. 条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
3. 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态 。
4. 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

有限状态机 FSM 实现

用while{switch/case}(推荐可读性高) 或 if/else 实现,简单粗暴,适合简单的小型状态机;
用设计模式中的 state pattern,把复杂判断的逻辑简化,利于组织代码;
用状态表设计,建立状态表和动作查询表,根据状态表、事件、动作表定位相应的动作处理函数,执行完成后再进行状态的切换;

函数指针实现的FSM的实例

  1. // https://github.com/AstarLight/FSM-framework/blob/master/main.c
  2. #include <stdio.h>
  3. //#include <windows.h> //windows
  4. #include <unistd.h> //linux
  5.  
  6. //比如我们定义了小明一天的状态如下
  7. enum
  8. {
  9. GET_UP,
  10. GO_TO_SCHOOL,
  11. HAVE_LUNCH,
  12. DO_HOMEWORK,
  13. SLEEP,
  14. };
  15.  
  16. //我们定义的事件有以下几个
  17. enum
  18. {
  19. EVENT1 = ,
  20. EVENT2,
  21. EVENT3,
  22. };
  23.  
  24. typedef struct FsmTable_s
  25. {
  26. int event; //事件
  27. int CurState; //当前状态
  28. void (*eventActFun)(); //函数指针
  29. int NextState; //下一个状态
  30. }FsmTable_t;
  31.  
  32. typedef struct FSM_s
  33. {
  34. FsmTable_t* FsmTable; //指向的状态表
  35. int curState; //FSM当前所处的状态
  36.  
  37. }FSM_t;
  38.  
  39. int g_max_num; //状态表里含有的状态个数
  40.  
  41. void GetUp()
  42. {
  43. // do something
  44. printf("xiao ming gets up!\n");
  45.  
  46. }
  47.  
  48. void Go2School()
  49. {
  50. // do something
  51. printf("xiao ming goes to school!\n");
  52. }
  53.  
  54. void HaveLunch()
  55. {
  56. // do something
  57. printf("xiao ming has lunch!\n");
  58. }
  59.  
  60. void DoHomework()
  61. {
  62. // do something
  63. printf("xiao ming does homework!\n");
  64. }
  65.  
  66. void Go2Bed()
  67. {
  68. // do something
  69. printf("xiao ming goes to bed!\n");
  70. }
  71.  
  72. /*状态机注册*/
  73. void FSM_Regist(FSM_t* pFsm, FsmTable_t* pTable)
  74. {
  75. pFsm->FsmTable = pTable;
  76. }
  77.  
  78. /*状态迁移*/
  79. void FSM_StateTransfer(FSM_t* pFsm, int state)
  80. {
  81. pFsm->curState = state;
  82. }
  83.  
  84. /*事件处理*/
  85. void FSM_EventHandle(FSM_t* pFsm, int event)
  86. {
  87. FsmTable_t* pActTable = pFsm->FsmTable;
  88. void (*eventActFun)() = NULL; //函数指针初始化为空
  89. int NextState;
  90. int CurState = pFsm->curState;
  91. int flag = ; //标识是否满足条件
  92.  
  93. /*获取当前动作函数*/
  94. for (int i = ; i<g_max_num; i++)
  95. {
  96. //当且仅当当前状态下来个指定的事件,我才执行它
  97. if (event == pActTable[i].event && CurState == pActTable[i].CurState)
  98. {
  99. flag = ;
  100. eventActFun = pActTable[i].eventActFun;
  101. NextState = pActTable[i].NextState;
  102. break;
  103. }
  104. }
  105.  
  106. if (flag) //如果满足条件了
  107. {
  108. /*动作执行*/
  109. if (eventActFun)
  110. {
  111. eventActFun();
  112. }
  113.  
  114. //跳转到下一个状态
  115. FSM_StateTransfer(pFsm, NextState);
  116. }
  117. else
  118. {
  119. // do nothing
  120. }
  121. }
  122.  
  123. FsmTable_t XiaoMingTable[] =
  124. {
  125. //{到来的事件,当前的状态,将要要执行的函数,下一个状态}
  126. { EVENT1, SLEEP, GetUp, GET_UP },
  127. { EVENT2, GET_UP, Go2School, GO_TO_SCHOOL },
  128. { EVENT3, GO_TO_SCHOOL, HaveLunch, HAVE_LUNCH },
  129. { EVENT1, HAVE_LUNCH, DoHomework, DO_HOMEWORK },
  130. { EVENT2, DO_HOMEWORK, Go2Bed, SLEEP },
  131.  
  132. //add your codes here
  133. };
  134.  
  135. //初始化FSM
  136. void InitFsm(FSM_t* pFsm)
  137. {
  138. g_max_num = sizeof(XiaoMingTable) / sizeof(FsmTable_t);
  139. pFsm->curState = SLEEP;
  140. FSM_Regist(pFsm, XiaoMingTable);
  141. }
  142.  
  143. //测试用的
  144. void test(int *event)
  145. {
  146. if (*event == )
  147. {
  148. *event = ;
  149. }
  150. else
  151. {
  152. (*event)++;
  153. }
  154.  
  155. }
  156.  
  157. int main()
  158. {
  159. FSM_t fsm;
  160. InitFsm(&fsm);
  161. int event = EVENT1;
  162. //小明的一天,周而复始的一天又一天,进行着相同的活动
  163. while ()
  164. {
  165. printf("event %d is coming...\n", event);
  166. FSM_EventHandle(&fsm, event);
  167. printf("fsm current state %d\n", fsm.curState);
  168. test(&event);
  169. sleep(); //休眠1秒,方便观察
  170. }
  171.  
  172. return ;
  173. }

有限状态机FSM的更多相关文章

  1. 有限状态机FSM(自动售报机Verilog实现)

    有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...

  2. cocos2d-x 游戏开发之有限状态机(FSM) (四)

    cocos2d-x 游戏开发之有限状态机(FSM) (四) 虽然我们了解了FSM,并且可以写自己的FSM,但是有更好的工具帮我们完成这个繁琐的工作.SMC(http://smc.sourceforge ...

  3. cocos2d-x 游戏开发之有限状态机(FSM) (三)

    cocos2d-x 游戏开发之有限状态机(FSM) (三) 有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态.然后Monkey类就实现了行为与状态分离.Monk ...

  4. cocos2d-x 游戏开发之有限状态机(FSM) (一)

    cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游 ...

  5. cocos2d-x 游戏开发之有限状态机(FSM) (二)

    cocos2d-x 游戏开发之有限状态机(FSM)  (二) 1 状态模式

  6. Atitit. 有限状态机 fsm 状态模式

    Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Even ...

  7. [原创][FPGA]有限状态机FSM学习笔记(一)

    1. 概述--何为有限状态机FSM? 有限状态机-Finite State Machine,简写为FSM,是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.通常 ...

  8. Linux编程之有限状态机FSM的理解与实现

    有限状态机(finite state machine)简称FSM,表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.FSM是一种逻辑单元内部的一种高效编程方法,在 ...

  9. 有限状态机(FSM)的Java 学习FSM

    本文从简单的例子入手,逐步演变成非常复杂的程序. 在简明 状态模式(5.8)中,状态之间的变换由外界控制,或者说,多种状态是分割的.无关的.状态模式最有趣的地方正是讨论其状态的变迁. 1.引子 空调( ...

随机推荐

  1. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.mybatis.spring.mapper.MapperScannerConfigurer#0'

    七月 05, 2018 10:26:54 上午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRul ...

  2. eclipse中将Java项目转换为JavaWeb项目

    eclipse导入一些war项目后,会以java项目形式存在,因此我们需要将java项目转换成web项目,不然项目也许会报错. 1.右键已经导入的项目,选择properties. 2.选中projec ...

  3. MySQL创建远程用户并授权

    今天需要在本地测试系统功能,因为本地没有数据库,就需要在程序里面连接远程数据库: 先用ssh登录远程服务器,用root连上数据库看看情况: mysql> select Host,User,Pas ...

  4. js定时函数,定时改变字体的大小

    <html> <head> </head> <body> <div id="d"> js控制字体大小 </div& ...

  5. java split(regex,limit) 使用记录

    1.split(“,”,0):是切割默认模式等同于split(",")结尾符合分割字符为空不进行进行分割,如图: 2.split(",",-1):limit参数 ...

  6. codeforces534B

    Covered Path CodeForces - 534B The on-board computer on Polycarp's car measured that the car speed a ...

  7. 【数学建模】day04-插值与拟合

    关于插值原理,这篇文章里总结过. 插值,是在有限个数据点的情况下,模拟出更多的点来适应实际问题的需要. 拟合,是在已知数据点基础上,以已知点处最小误差为标准,模拟出近似函数. 二者有似,实则不同,ma ...

  8. shelve 模块

    shelve 模块概述:   shelve是python的自带model.   可以直接通过import shelve来引用.   shelve类似于一个存储持久化对象的持久化字典,即字典文件.   ...

  9. BZOJ 3261 最大异或和(算竞进阶习题)

    可持久化Trie 需要知道一个异或的特点,和前缀和差不多 a[p] xor a[p+1] xor....xor a[n] xor x = a[p-1] xor a[n] xor x 所以我们把a[1. ...

  10. 多IP加强SSH的安全性

    本文针对一台服务器有多个网卡及IP地址的情况,可以限制某些IP不监听SSH,只允许通过某些IP来登陆 以下配置项在/etc/ssh/sshd_config文件中修改 比如你有4个网卡: eth0 – ...