结构定义
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
春秋十二月 阅读(3997)
评论(1) 编辑 收藏 引用 所属分类:
C/C++