【问题标题】:Boost Meta State Machine ends up with stack overflow when deferring an event延迟事件时,Boost Meta State Machine 以堆栈溢出结束
【发布时间】:2011-04-15 06:27:21
【问题描述】:

我有一些代码可以实现基于 Boost MSM 库的状态机。在我不得不添加一个延迟事件仿函数前端的行之前,它一直运行良好:

Row < StateX, Event1, none, Defer, none >

现在,只要这一行被命中,线程就会以一个打击堆栈结束。我跟踪了 MSM 中的方法调用,不幸的是,一切似乎都按设计工作。以下是执行步骤:

  1. 使用 Event1 调用 process_event
  2. Event1 被添加到 Defer 函子内的延迟事件队列中
  3. 由于该行已成功处理,handled 设置为 TRUE
  4. 在 process_event 结束时,有处理无事件转换的代码。需要此代码,因为如果事件导致从状态 A 移动到 B,B 可能会自动转换到不同的状态,这是唯一会处理这些的地方(在我的代码中,我没有使用任何这些,但逻辑仍然被调用)
  5. eventless_helper 使用“none”类型的事件调用 process_event
  6. 在处理“无”(没有实际工作)时,代码现在发现队列中有一个延迟事件,因此将其出列并再次调用 process_event。
  7. 现在我们重复第 1 步中的所有内容,但我们仍处于上一步的函数内部,所以这一直持续到我们耗尽堆栈为止。

似乎延迟事件的逻辑与处理无事件转换的逻辑发生冲突,我很想进入 boost 代码并破解后者。似乎如果事件被“延迟”,则不应将其视为已处理,如果是这种情况,则不会触发无事件转换(因为它们不应该触发),但是状态机最终会在一个 no_transition 调用,它本质上是一个包罗万象的意外错误处理程序。这还需要入侵我希望避免的库代码。

但在我做任何事情之前,我想看看其他人是否发现了这个。或者给我关于在哪里获得帮助的建议。

更新: 显然,我公司使用的 Boost Library 版本是 1.44,并且在该版本中存在延迟事件处理的错误。它已在 1.46.1 中修复。

【问题讨论】:

  • 没错,1.44 中存在一个错误,正如您所发现的,它已在 1.46 中修复。如果由于某种原因你被 1.44 卡住了,你可以通过添加到任何状态定义中来强制激活延迟事件来解决这个错误: typedef mpl::vector* any event */> deferred_events;

标签: c++ boost


【解决方案1】:

获得适当帮助的最佳地点是boost user's mailing list。 Christophe 非常擅长回应可能的错误报告,但我认为他不会这么看。

或者,您也可以直接给 Christophe 发送电子邮件,因为我知道他很乐意这样做。我不会在这里发布他的电子邮件地址,但在 gmane boost 邮件列表档案中很容易找到。

【讨论】:

  • 感谢您的提示。我想我在某个地方读到过,虽然每个人都可以阅读 boost 邮件列表,但只能通过邀请才能在上面发帖。你知道这是真的还是假的?我的印象是我不能去那里随便发一个问题。
  • @DXM :不,那一点也不真实。如果您之前从未在 ML 上发过帖子,那么您的帖子必须由版主批准,然后在发布一些非垃圾邮件帖子后,您将被列入白名单,提供自动批准。但是,在您进入白名单之前,您只需等到主持人开始处理它,这通常是即时的,很少超过一两个小时。
  • 谢谢 :) 我有时会看一下 SO,但不是很经常,所以在 ML 上发帖或给我发电子邮件会给你一个更快的答案(通常是一两天)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 2021-05-28
  • 2011-05-16
相关资源
最近更新 更多