随笔-89  评论-224  文章-23  trackbacks-0
结构定义
 1 struct state_machine {
 2     int state;
 3     
 4 };
 5 
 6 enum { 
 7     s1,
 8     s2,
 9     
10     sn
11 };
   假设s1为初始状态,状态变迁为s1->s2->...->sn。

常规实现 
   状态机处理函数state_machine_handle通常在一个循环内或被事件驱动框架调用,输入data会随时序变化,从而引起状态的变迁,伪代码框架如下。
 1void handle_s1(struct state_machine *sm, void *data)
 2{
 3    //do something about state 1
 4    if(is_satisfy_s2(data))
 5        sm->state = s2;
 6}

 7
 8void handle_s2(struct state_machine *sm, void *data)
 9{
10    //do something about state 2
11    if(is_satisfy_s3(data))
12        sm->state = s3;
13}

14
15void handle_sn_1(struct state_machine *sm, void *data)
16{
17    //do something about state n-1
18    if(is_satisfy_sn(data))
19        sm->state = sn;
20}

21
22void state_machine_handle(struct state_machine *sm, void *data)
23{
24    switch(sm->state){
25        case s1:
26            handle_s1(sm,data);
27            break;
28            
29        case s2:
30            handle_s2(sm,data);
31            break;            
32            
33        case sn:
34            handle_sn(sm,data);
35            break;
36    }

37}
   sm->state初始化为s1。

改进实现
   为了免去丑陋的switch case分支结构,在state_machine内用成员函数指针handler替代了state,改进后的框架如下。
 1struct state_machine;
 2typedef void (*state_handler)(struct state_machine*void*);
 3
 4struct state_machine {
 5    state_handler handler;
 6    
 7}
;
 8
 9void handle_s1(struct state_machine *sm, void *data)
10{
11    //do something about state 1
12    if(is_satisfy_s2(data))
13        sm->handler = handle_s2;
14}

15
16void handle_s2(struct state_machine *sm, void *data)
17{
18    //do something about state 2
19    if(is_satisfy_s3(data))
20        sm->handler = handle_s3;
21}

22
23void handle_sn_1(struct state_machine *sm, void *data)
24{
25    //do something about state n-1
26    if(is_satisfy_sn(data))
27        sm->handler = handle_sn;
28}

29
30void state_machine_handle(struct state_machine *sm, void *data)
31{
32    sm->handler(sm, data);
33}
   sm->handler初始化为handle_s1,该方法在性能上应略优于常规方法,而且逻辑更清晰自然,非常适合于网络流的处理,在nginx中分析http和email协议时,得到了广泛应用。
posted on 2016-05-05 09:46 春秋十二月 阅读(2259) 评论(1)  编辑 收藏 引用 所属分类: C/C++

评论:
# re: 一种使用函数指针实现状态机的方法 2016-05-04 23:27 | linda
函数指针实现状态机  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理