结构定义
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是变化的,不同的data会改变状态,伪代码框架如下。
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。
改进实现
为了免去丑陋的switch case分支结构,用成员函数指针handler替代了state,改进后的框架如下。
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,该方法在性能上应略优于常规方法,而且逻辑更清晰自然,非常适合于网络流的处理,在nginx中分析http和email协议时,得到了广泛应用。