4

我想使用 boost msm 状态机,但我很难想象它是如何工作的。假设我们只有 2 个状态(s1,s2),要从 s1 转到 s2,您需要触发事件 e1,而要返回则需要另一个 e2。e1 和 e2 只能分别从 s1 和 s2 内触发。

现在在 main() 中,我首先启动状态机 (start()),然后会有一个 while 循环,每 1 分钟将返回到状态机,但必须从它离开的地方继续。

main()
{
 MSM.start(); //start state machine

 while (a_condition)
 {
 ProcessInputsfromIO();
 Go_backtoStatemachine(); //how can i do this?
 delay(1min)
 }
 MSM.stop();
}

所以基本上当一个状态完成执行时,状态机将退出,然后会有 1 分钟的延迟,然后 while 循环需要将我带回到我退出之前的状态,或者我认为这就是我们应该如何实现状态机。

我的要求是不是很不寻常?如果是,那么人们如何实现非阻塞状态机?如果没有,那么我该如何实现 Go_backtoStatemachine()?

4

2 回答 2

3

这里有一个相当简单的例子:

MSM 简单教程

状态机是一个抽象概念。它有状态、事件等。它并没有真正的阻塞、非阻塞等概念。在Boost MSM的框架内,你可以调用start()进入初始状态、process_event()注入事件和stop()停止。状态机只是简单地捕获系统状态,并且可以在系统改变状态时调用一些函数。你将如何使用它是非常依赖于应用程序的。

于 2012-03-05T01:15:58.387 回答
0

MSM 对线程一无所知,所以当start()process_event(MyEvent())被调用时,它们会在当前线程上执行。正如文档(https://www.boost.org/doc/libs/1_75_0/libs/msm/doc/ HTML/ch03s05.html#d0e2668):

将事件排入队列以供以后处理

调用 process_event(Event const&) 将立即处理具有运行到完成语义的事件。您还可以通过调用 enqueue_event(Event const&) 将事件排入队列并延迟其处理。然后调用 execute_queued_events() 将处理所有排队的事件(按 FIFO 顺序)。调用 execute_single_queued_event() 将执行最早的排队事件。

您可以通过调用 get_message_queue_size() 来查询队列大小。

那么在问题的示例中,您可以

  1. 将 ProcessInputsfromIO 中的事件排入队列为
void ProcessInputsfromIO(){
    somethingToDo();
    myfsm.enqueue_event(myEvent1());
    somethingElseToDo();
    etc();
}
  1. Go_backtoStatemachine() 变成了简单的 myfsm.execute_queued_events()
于 2021-02-17T12:52:50.257 回答