C++11 Boost元状态机无限循环Seg故障

C++11 Boost元状态机无限循环Seg故障,c++11,boost,uml,state-machine,boost-msm,C++11,Boost,Uml,State Machine,Boost Msm,我试图使用Boost状态机,但在无限循环中运行我的机器时遇到了分段错误。本质上,我在boost状态机函子示例中有相同的示例,如下所示: 唯一的区别是,我现在一进入State4就触发“event1”,从而创建了一个循环。这可以运行数千次迭代,但随后会出现seg故障。我是否违反了某种UML规则并溢出了堆栈?我基本上只有一个阻塞事件,然后我希望所有其他状态自动触发,然后以State4结束(例如,实际上是等待网络消息的阻塞调用)。如何使用元状态机正确地实现这一点,以避免炸毁堆栈 更新 我在这里包含了导

我试图使用Boost状态机,但在无限循环中运行我的机器时遇到了分段错误。本质上,我在boost状态机函子示例中有相同的示例,如下所示:

唯一的区别是,我现在一进入State4就触发“event1”,从而创建了一个循环。这可以运行数千次迭代,但随后会出现seg故障。我是否违反了某种UML规则并溢出了堆栈?我基本上只有一个阻塞事件,然后我希望所有其他状态自动触发,然后以State4结束(例如,实际上是等待网络消息的阻塞调用)。如何使用元状态机正确地实现这一点,以避免炸毁堆栈

更新
我在这里包含了导致问题的源代码:

这基本上是functor前端中的示例,但有以下更改:

增加了“假装”阻塞调用功能:

  struct BlockingCall {
    template <class EVT, class FSM, class SourceState, class TargetState>
    void operator()(EVT const &, FSM &, SourceState &, TargetState &) {
      std::cout << "my_machine::Waiting for a thing to happen..." << std::endl;
      // Pretend I'm actually waiting for something
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      std::cout << "my_machine::OMG the the thing happened!" << std::endl;
    }
  };
现在我一直在全速奔跑(不睡觉),而且我没有出现seg故障。基于此,似乎没有办法启动状态机,让它运行并处理内部事件,对吗?我总是需要在外面有一些过程,至少在偶数点触发

更新3 最终,我的目标是实现如下图所示的内容:


我的目的是启动状态机,然后它将简单地等待传入的消息,而不进行任何进一步的干预。

我得出的结论是,如果调用
fsm.process\u event(e1),状态机根本不可能有内部循环
在任何操作/防护/进入/退出语句中。我认为问题在于每次调用时,都会在堆栈上推送更多信息,直到最终溢出堆栈。如果匿名转换在状态机中创建无限循环,则也是如此。所以我的结论是,必须至少有一个外部事件来触发循环。因此,以下代码是我迄今为止找到的最佳解决方案:

void test() {
  my_machine p;
  p.start();
  // Must have at least 1 triggering external event to not overflow the stack
  while (true) {
    p.process_event(event1());
  }
}

我得出的结论是,如果在任何操作/保护/进入/退出语句中调用
fsm.process\u event(e1)
,状态机根本不可能有内部循环。我认为问题在于每次调用时,都会在堆栈上推送更多信息,直到最终溢出堆栈。如果匿名转换在状态机中创建无限循环,则也是如此。所以我的结论是,必须至少有一个外部事件来触发循环。因此,以下代码是我迄今为止找到的最佳解决方案:

void test() {
  my_machine p;
  p.start();
  // Must have at least 1 triggering external event to not overflow the stack
  while (true) {
    p.process_event(event1());
  }
}

你应该发布一个@m.s.我已经用你的建议更新了我的问题。虽然我无法回答Wesson如何在特定工具中实现它,但我将仅限于发表评论。从UML的角度来看,lip不一定是有限的。事实上,状态机通常是无限的,然而通常一个或多个状态被认为是最终的。然而,在实际实现中,您可能会遇到许多问题,而无限循环往往会暴露这些问题。由于工具的限制,绝对有效的UML状态机可能无法在您选择的工具中实现。谢谢您的回复。我很高兴知道,至少我的状态图在技术上没有错,但有一个实现细节不允许我以我最初打算的方式来实现它。你应该发布一个@m.s。我已经用你的建议更新了我的问题。虽然我无法回答Wesson如何在特定工具中实现它,我将仅限于发表评论。从UML的角度来看,lip不一定是有限的。事实上,状态机通常是无限的,然而通常一个或多个状态被认为是最终的。然而,在实际实现中,您可能会遇到许多问题,而无限循环往往会暴露这些问题。由于工具的限制,绝对有效的UML状态机可能无法在您选择的工具中实现。谢谢您的回复。我很高兴地知道,至少我的状态图在技术上没有错,但是有一个实现细节不允许我以我最初打算的方式来实现它。
void test() {
  my_machine p;

  // needed to start the highest-level SM. This will call on_entry and mark the
  // start of the SM
  // in this case it will also immediately trigger all anonymous transitions
  p.start();
  // this event will bring us back to the initial state and thus, a new "loop"
  // will be started
  while (true) {
    p.process_event(event1());
  }
}
void test() {
  my_machine p;
  p.start();
  // Must have at least 1 triggering external event to not overflow the stack
  while (true) {
    p.process_event(event1());
  }
}