免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6373 | 回复: 3
打印 上一主题 下一主题

怎么在程序里面实现状态机呢 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-09-06 16:15 |只看该作者 |倒序浏览
老是听一些高人提状态机,状态机有甚么用处,有甚么好处, 状态机和异步模式有甚么关系, 总之是好多问题困扰着我。

如果哪位大哥有现成的code,展示一些甚么是状态机,在程序中如何实现,那就真是不胜感激了

[ 本帖最后由 zjia2 于 2006-9-6 16:32 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-09-06 16:41 |只看该作者
状态机...随便找一本离散数学、算法之类的书里面就有。

下面的是一个简单的状态机,作用是解析 Oracle 一个备份程序输出的信息,判断备份是否成功。


  1. /**
  2. * A state machine to determine whether db backup success.
  3. */
  4. class StateMachine {
  5. private:
  6.         // state machine states
  7.         enum {
  8.                 SM_NORMAL,                        // in backup
  9.                 SM_NEW_LINE,                // new line begin
  10.                 SM_CHAR_EXPECTED,        // expect an character (error condition is about to start)
  11.                 SM_BAR_EXPECTED,        // expect a '-'
  12.                 SM_NUM_EXPECTED,        // expect a number
  13.                 SM_COLON_EXPECTED,        // expect a ':'
  14.         };
  15.         bool backupStart;
  16.         bool error;                                // error occure
  17.         int errorState;                        // error state
  18.         int state;                                // state machine state

  19.         int charNum;                        // number of char readed in error condition
  20.         int digitNum;                        // number of digit readed in error condition
  21.         std::string errMsg;                // error message

  22. public:
  23.         // error states
  24.         enum {
  25.                 OB_OK = 0,

  26.                 EXP_ERROR,                                // unclassified client error
  27.                 EXP_ID_ERROR,                        // client error: invalid user name and/or password

  28.                 ORA_ERROR,                                // unclassified oracle error
  29.                 ORA_ID_ERROR,                        // user name and password error
  30.                 ORA_NO_CONNECTION,                // no network adapter
  31.                 ORA_CONNECTION_TIMEOUT,        // can't make connection to host
  32.                 ORA_CONNECTION_BROKEN,        // network connection broken
  33.         };

  34.         StateMachine(void)
  35.                 : error(true)
  36.                 , errorState(OB_OK)
  37.                 , backupStart(false)
  38.                 , state(SM_NORMAL)
  39.                 , charNum(0)
  40.                 , digitNum(0)
  41.         {
  42.         }

  43.         int parse(int c) {
  44.                 switch (state) {
  45.                 case SM_NORMAL:
  46.                         if (c == '\n')
  47.                                 state = SM_NEW_LINE;
  48.                         break;

  49.                 case SM_NEW_LINE:
  50.                         if (c == '.') {
  51.                                 state = SM_NORMAL;

  52.                                 error = true;
  53.                                 backupStart = true;
  54.                         } else if ((c != ' ') && (c != '\t')) {
  55.                                 if (isalpha(c)) {
  56.                                         state = SM_CHAR_EXPECTED;        // an error is about to occur

  57.                                         errMsg = "";
  58.                                         errMsg += c;
  59.                                         charNum = 1;
  60.                                         digitNum = 0;
  61.                                 } else {                                                // ignore other character
  62.                                         state = SM_NORMAL;
  63.                                 }

  64.                                 if (backupStart) {
  65.                                         // if backup started and no error occured,
  66.                                         // this maybe a successful message.
  67.                                         if (errorState == OB_OK) {
  68.                                                 error = false;
  69.                                         }
  70.                                 } else {
  71.                                         error = true;
  72.                                 }
  73.                         }
  74.                         break;

  75.                 case SM_CHAR_EXPECTED:
  76.                         if (isalpha(c)) {
  77.                                 errMsg += c;
  78.                                 ++charNum;
  79.                                 if (charNum == 3) {
  80.                                         state = SM_BAR_EXPECTED;
  81.                                 }
  82.                         } else {
  83.                                 state = SM_NORMAL;
  84.                         }
  85.                         break;

  86.                 case SM_BAR_EXPECTED:
  87.                         if (c == '-') {
  88.                                 errMsg += c;
  89.                                 state = SM_NUM_EXPECTED;
  90.                                 if (errMsg == "EXP-") {
  91.                                         errorState = EXP_ERROR;
  92.                                 } else if (errMsg == "ORA-") {
  93.                                         errorState = ORA_ERROR;
  94.                                 } else {
  95.                                         state = SM_NORMAL;
  96.                                 }
  97.                         } else {
  98.                                 state = SM_NORMAL;
  99.                         }
  100.                         break;

  101.                 case SM_NUM_EXPECTED:
  102.                         if (isdigit(c)) {
  103.                                 errMsg += c;
  104.                                 ++digitNum;
  105.                                 if (digitNum == 5) {                        // error detected
  106.                                         state = SM_COLON_EXPECTED;
  107.                                 }
  108.                         } else {                                                // not an error message
  109.                                 state = SM_NORMAL;
  110.                                 errorState = OB_OK;
  111.                         }
  112.                         break;

  113.                 case SM_COLON_EXPECTED:
  114.                         if (c == ':') {
  115.                                 state = SM_NORMAL;

  116.                                 error = true;

  117.                                 switch (errorState) {
  118.                                 case EXP_ERROR:
  119.                                         if (errMsg == "EXP-00004") {
  120.                                                 errorState = EXP_ID_ERROR;
  121.                                                 return EXP_ID_ERROR;
  122.                                         }
  123.                                         return EXP_ERROR;
  124.                                         break;

  125.                                 case ORA_ERROR:
  126.                                         if (errMsg == "ORA-01017") {
  127.                                                 errorState = ORA_ID_ERROR;
  128.                                                 return ORA_ID_ERROR;
  129.                                         } else if ((errMsg == "ORA-03113")
  130.                                                         || (errMsg == "ORA-03114")) {
  131.                                                 errorState = ORA_CONNECTION_BROKEN;
  132.                                                 return ORA_CONNECTION_BROKEN;
  133.                                         } else if ((errMsg == "ORA-12535")
  134.                                                         || (errMsg == "ORA-12170")) {
  135.                                                 errorState = ORA_CONNECTION_TIMEOUT;
  136.                                                 return ORA_CONNECTION_TIMEOUT;
  137.                                         } else if (errMsg == "ORA-12560") {
  138.                                                 errorState = ORA_NO_CONNECTION;
  139.                                                 return ORA_NO_CONNECTION;
  140.                                         }
  141.                                         return ORA_ERROR;
  142.                                         break;
  143.                                 }
  144.                         } else {
  145.                                 state = SM_NORMAL;
  146.                                 errorState = OB_OK;
  147.                         }
  148.                         break;

  149.                 default:
  150.                         state = SM_NORMAL;
  151.                         break;
  152.                 }

  153.                 return OB_OK;
  154.         }

  155.         void reset(void) {
  156.                 state = SM_NORMAL;
  157.                 error = true;
  158.         }

  159.         int getState(void) {
  160.                 if (error)
  161.                         return -1;
  162.                 else
  163.                         return 0;
  164.         }
  165. };
复制代码

论坛徽章:
0
3 [报告]
发表于 2006-09-06 17:24 |只看该作者
多谢回答,但是状态机和和程序的异步执行有关系吗?

论坛徽章:
0
4 [报告]
发表于 2006-09-06 17:34 |只看该作者
参看IEEE 802.1x协议的的文档。然后对照xsupplicant中的相关的代码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP