增强MSM—更清晰

Boost MSM - clearer

本文关键字:清晰 MSM 增强      更新时间:2023-10-16

我想使用boost msm状态机,但我很难想象它是如何工作的。假设我们只有两个状态(s1,s2),要从s1到s2,需要触发事件e1,要返回bo,需要另一个事件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()?

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

MSM简单教程

状态机是一个抽象概念。它有状态、事件等。它实际上没有阻塞、非阻塞等概念。在Boost MSM的框架内,您可以调用start()进入初始状态,process_event()注入事件,stop()停止。状态机只是捕获系统状态,并可以在系统更改状态时调用一些函数。如何使用它取决于应用程序。

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()