【发布时间】:2013-06-06 20:54:33
【问题描述】:
我想实现一个状态机,它会定期监控一些状态数据(我系统的状态)并对其做出反应。
这对于状态机来说似乎是非常基本的事情(我以前曾多次遇到过这个问题),但我找不到一个好的方法来解决它。这是一些伪代码来解释我想要实现的目标:
// some data that is updated from IOs for example
MyData data;
int state = 0;
while( true ) {
update( & data ); //read a packet from serial port
//and update the data structure
switch( state ) {
case 0:
if( data.field1==0 ) state = 1;
else doSomething();
break;
case 1:
if( data.field2>0 ) state = 2;
else doSomethingElse();
break;
// etc.
}
usleep(100000); //100ms
}
当然,最重要的是,我希望能够在进入和退出状态时执行一些操作,可能在状态的每次迭代中执行一些操作,拥有子状态、历史记录等。这就是为什么这种简单化方法的原因很快变得不切实际,因此提升状态图。
我已经考虑了一些解决方案,希望得到一些反馈。
1) 我可以列出我的所有转换条件并为每个条件创建一个事件。然后我会有一个循环来监控每个布尔切换的时间。例如我的第一个条件可能是:
if( old_data.field1!=0 && new_data.field1==0 )
// post an event of type Event 1
但似乎很快就会变得困难
2) 有一个所有状态都响应的事件。只要有一些新的状态数据可用,就会发布此事件。因此,当前状态将检查数据并决定是否启动到另一个状态的转换
3) 让所有状态都继承自定义 do_work(const MyData & data) 方法的接口,该方法将在循环中从外部调用,检查数据并决定是否启动到另一个状态的转换
另外,我愿意使用其他框架(即 Macho 或 boost MSM)
【问题讨论】:
-
也许您可以在 state-machine.com 上查看带有分层状态机的 QP 活动对象框架。你不写你想在哪个操作系统/环境上运行它,但从 usleep() 调用来看,它看起来像 POSIX,QP 多年来一直支持它。
-
全面披露 Miro(上面评论过的)是 QP 的作者,所以他正在开发自己的产品;)我强烈推荐他的书。
标签: state state-machine fsm boost-statechart boost-msm