Linux有限状态机FSM的理解与实现

  

有限状态机(有限状态机)简称FSM,表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.FSM是一种逻辑单元内部的一种高效编程方法,在服务器编程中,服务器可以根据不同状态或者消息类型进行相应的处理逻辑,使得程序逻辑清晰易懂。

  

  

处理程序语言或者自然语言的记号赋予器,自底向上解析语法的解析器,
  各种通信协议发送方和接受方传递数据对消息处理,游戏AI等都有应用场景。

  

状态机有以下几种实现方法,我将一一阐述它们的优缺点。

  

<强>一、使用if/else if语句实现的FSM
  强使用if/else if语句是实现的FSM最简单最易懂的方法,我们只需要通过大量的if/else if语句来判断状态值来执行相应的逻辑处理。

  

看看下面的例子,我们使用了大量的if/else if语句实现了一个简单的状态机,做到了根据状态的不同执行相应的操作,并且实现了状态的跳转。

     //比如我们定义了小明一天的状态如下   枚举   {   GET_UP,   GO_TO_SCHOOL,   HAVE_LUNCH,   GO_HOME,   DO_HOMEWORK,   睡眠,   };         int main ()   {   int状态=GET_UP;//小明的一天   而(1)   {   如果(状态==GET_UP)   {   服饰();//具体调用的函数   状态=GO_TO_SCHOOL;//状态的转移   }   else if(国家==GO_TO_SCHOOL)   {   Go2School ();   状态=HAVE_LUNCH;   }   else if(国家==HAVE_LUNCH)   {   HaveLunch ();   }   …   else if(睡眠状态==)   {   Go2Bed ();   状态=GET_UP;   }   }      返回0;   }      之前      

看完上面的例子,大家有什么感受?是不是感觉程序虽然简单易懂,但是使用了大量的如果判断语句,使得代码很低端,同时代码膨胀的比较厉害。这个状态机的状态仅有几个,代码膨胀并不明显,但是如果我们需要处理的状态有数十个的话,该状态机的代码就不好读了

。   

<强>二、使用开关实现FSM
  

  

使用开关语句实现的FSM的结构变得更为清晰了,其缺点也是明显的:这种设计方法虽然简单,通过一大堆判断来处理,适合小规模的状态切换流程,但如果规模扩大难以扩展和维护。

        int main ()   {   int状态=GET_UP;//小明的一天   而(1)   {      开关(状态)   {   案例GET_UP:   服饰();//具体调用的函数   状态=GO_TO_SCHOOL;//状态的转移   打破;   案例GO_TO_SCHOOL:   Go2School ();   状态=HAVE_LUNCH;   打破;   案例HAVE_LUNCH:   HaveLunch ();   状态=GO_HOME;   打破;   …   默认值:   打破;   }   }      返回0;   }      之前      

<强>三、使用函数指针实现FSM
  

  

使用函数指针实现FSM的思路:建立相应的状态表和动作查询表,根据状态表,事件,动作表定位相应的动作处理函数,执行完成后再进行状态的切换。

  

当然使用函数指针实现的FSM的过程还是比较费时费力,但是这一切都是值得的,因为当你的程序规模大时候,基于这种表结构的状态机,维护程序起来也是得心应手。

  

下面给出一个使用函数指针实现的FSM的框架:

  

我们还是以“小明的一天”为例设计出该FSM。

  

先给出该FSM的状态转移图:

  

癓inux有限状态机FSM的理解与实现"

  

下面讲解关键部分代码实现

  

首先我们定义出小明一天的活动状态

     //比如我们定义了小明一天的状态如下   枚举   {   GET_UP,   GO_TO_SCHOOL,   HAVE_LUNCH,   DO_HOMEWORK,   睡眠,   };   之前      

我们也定义出会发生的事件

        枚举   {   EVENT1=1,   EVENT2,   EVENT3,   };   之前      

定义状态表的数据结构

        typedef struct FsmTable_s   {   int事件;//事件   int CurState;//当前状态   空白(* eventActFun) ();//函数指针   int NextState;//下一个状态   }FsmTable_t;   之前      

接下来定义出最重要FSM的状态表,我们整个FSM就是根据这个定义好的表来运转的。

Linux有限状态机FSM的理解与实现