結(jié)構(gòu)定義
1 struct state_machine {
2 int state;
3
4 };
5 6 enum {
7 s1,
8 s2,
9
10 sn
11 };
假設(shè)s1為初始狀態(tài),狀態(tài)變遷為s1->s2->...->sn。
常規(guī)實現(xiàn) 狀態(tài)機(jī)處理函數(shù)state_machine_handle通常在一個循環(huán)內(nèi)或被事件驅(qū)動框架調(diào)用,輸入data會隨時序變化,從而引起狀態(tài)的變遷,偽代碼框架如下。
1
void 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
8
void 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
15
void 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
22
void 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。
改進(jìn)實現(xiàn)
為了免去丑陋的switch case分支結(jié)構(gòu),在state_machine內(nèi)用成員函數(shù)指針handler替代了state,改進(jìn)后的框架如下。
1
struct state_machine;
2
typedef void (*state_handler)(struct state_machine*,void*);
3
4
struct state_machine
{
5
state_handler handler;
6

7
};
8
9
void 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
16
void 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
23
void 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
30
void state_machine_handle(struct state_machine *sm, void *data)
31

{
32
sm->handler(sm, data);
33
}
sm->handler初始化為handle_s1,該方法在性能上應(yīng)略優(yōu)于常規(guī)方法,而且邏輯更清晰自然,非常適合于網(wǎng)絡(luò)流的處理,在nginx中分析http和email協(xié)議時,得到了廣泛應(yīng)用。
posted on 2016-05-05 09:46
春秋十二月 閱讀(4058)
評論(1) 編輯 收藏 引用 所屬分類:
C/C++