有限状态机实现

时间:2012-06-25 03:16:13

标签: c function-pointers fsm

我正在尝试在C中实现有限状态机并且需要它非常快。 所以我决定使用函数指针作为“状态”:

void *state1(void){ /* function body here */ }
void *state2(void){ /* ... */ }
void *state3(void){ /* ... */ }

然后,主FSM循环可以非常简单:

void *(*fp)(void);
fp = state1;

while(fp)
    fp = fp();

有一个问题:

1)是否可以避免在函数返回类型中使用void指针?理想情况下,状态函数应该有一些typedef类型,以确保在FSM中只使用这种类型的函数。

2)在C中实现FSM的传统方法是使用枚举用于状态和基于交换机的调度程序循环,因此与基于函数指针的实现相比,将存在一个间接级别。
但我不确定,指令缓存或分支预测有问题吗?换句话说,是否存在可以超越我的解决方案的实现?

感谢。

5 个答案:

答案 0 :(得分:3)

要在C中创建这样的递归类型定义,您需要在该行的某处使用struct,因为您无法转发声明"类型定义。例如,您可以将函数指针包装在struct

struct state {
    struct state (*func)(void);
};

然后在循环中:

struct state state = { state1 };

while (state.func) {
    state = state.func();
}

答案 1 :(得分:3)

您可以在此找到问题的答案:http://code.google.com/p/fwprofile/

它是实现的状态机的开源版本(GNU GPLv3) 在C.概念和实施非常适合用于 任务关键型应用程序。有工业部署 应用

答案 2 :(得分:1)

在C中不可能声明一个返回指向其自身类型函数的指针的函数。此外,您不能使用void *,因为C不允许在函数和对象指针之间进行转换。相反,您可以使用:

typedef void (*generic_func_ptr)(void);
typedef generic_func_ptr (*state_func_ptr)(void);
generic_func_ptr state1(void), state2(void), state3(void);
state_func_ptr fp;

while(fp)
    fp = (state_func_ptr)fp();

丑陋,但它确实有效。相反,我会考虑使用switch语句。这对于实现状态机来说更加清晰。

答案 3 :(得分:0)

1)typedef void(*state_fp)(void);

state_fp state1(void) { }

2)取决于,函数内置代码的小循环将比函数调用更快。例如,一个switch语句,其中每个状态都在switch语句中实现,但是,如果case语句太多,这将在函数调用下面降级

答案 4 :(得分:0)

如果其他人想要为fsm使用免费框架,请查看http://www.block-net.de/Programmierung/cpp/fsm/fsm.html 有一个C和C ++有限状态机框架,包括带有PlantUML的状态图生成器。