FSM的实现方法好像蛮多的, 用数组实现是比较常见的一种。
思路是这样的,用一个二维数组来保存在某个状态下遇到某种事件或激励时该执行哪个动作。二维数组中有多少“记录”就表示了状态机中有多少状态, 而“记录”中有多少栏表示了有多少种事件。 当然不是在所有的状态下,都会处理所有事件的。
有了这个概念,看代码就明白很多了。下面是个小例子,虽然不能运行,但其搭建起来的结构,却给以后的工作打下了良好的基础。
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include <stdio.h>
enum PROCESS_STATES
{
INIT,
RUNNING,
SLEEPING,
DEAD,
MAX_FSM_STATES
};
enum PROCESS_EVENT
{
START,
REQ_RESOURCE,
TERM,
MAX_FSM_EVENTS
};
void transaction_func1(void *param)
{
return;
}
typedef void (*fsm_action)(void *param);
typedef struct fsm_state_table {
/* List of actions when moving into this state from any other state */
const fsm_action action;
const fsm_action pre_action;
const fsm_action post_action;
} fsm_state_table;
// 这张就是重要的FSM数组了,定义了在某状态下收到某事件时,该执行什么动作
static const fsm_state_table
fsm_state_table_process[MAX_FSM_STATES][MAX_FSM_EVENTS] =
{
/* Current State = { { [Event] = func, ... } }, ... */
[INIT] =
{
[START] = {transaction_func1, },
[REQ_RESOURCE] = {transaction_func1, },
[TERM] = {transaction_func1, },
},
[RUNNING] =
{
[START] = {transaction_func1, },
[REQ_RESOURCE] = {transaction_func1, },
[TERM] = {transaction_func1, },
},
[SLEEPING] =
{
[START] = {transaction_func1, },
[REQ_RESOURCE] = {transaction_func1, },
[TERM] = {transaction_func1, },
},
[DEAD] =
{
[START] = {transaction_func1, },
[REQ_RESOURCE] = {transaction_func1, },
[TERM] = {transaction_func1, },
},
};
// 这个是执行FSM的地方, 其实就是一次执行FSM数组中的函数
int fsm(enum PROCESS_STATES current_state, enum PROCESS_EVENT event)
{
if(fsm_state_table_process[current_state][event].pre_action)
(*fsm_state_table_process[current_state][event].pre_action)(1);
if(fsm_state_table_process[current_state][event].action)
(*fsm_state_table_process[current_state][event].action)(1);
if(fsm_state_table_process[current_state][event].post_action)
(*fsm_state_table_process[current_state][event].post_action)(1);
// 必要的时候需要改变FSM的状态
return 0;
}
int main(int argc, char *argv[])
{
printf("max states %d, %d/n", INIT, MAX_FSM_STATES);
return 0;
}
好了,有了这个框架,以后有什么再加就好了。