【发布时间】:2011-04-15 06:27:21
【问题描述】:
我有一些代码可以实现基于 Boost MSM 库的状态机。在我不得不添加一个延迟事件仿函数前端的行之前,它一直运行良好:
Row < StateX, Event1, none, Defer, none >
现在,只要这一行被命中,线程就会以一个打击堆栈结束。我跟踪了 MSM 中的方法调用,不幸的是,一切似乎都按设计工作。以下是执行步骤:
- 使用 Event1 调用 process_event
- Event1 被添加到 Defer 函子内的延迟事件队列中
- 由于该行已成功处理,handled 设置为 TRUE
- 在 process_event 结束时,有处理无事件转换的代码。需要此代码,因为如果事件导致从状态 A 移动到 B,B 可能会自动转换到不同的状态,这是唯一会处理这些的地方(在我的代码中,我没有使用任何这些,但逻辑仍然被调用)
- eventless_helper 使用“none”类型的事件调用 process_event
- 在处理“无”(没有实际工作)时,代码现在发现队列中有一个延迟事件,因此将其出列并再次调用 process_event。
- 现在我们重复第 1 步中的所有内容,但我们仍处于上一步的函数内部,所以这一直持续到我们耗尽堆栈为止。
似乎延迟事件的逻辑与处理无事件转换的逻辑发生冲突,我很想进入 boost 代码并破解后者。似乎如果事件被“延迟”,则不应将其视为已处理,如果是这种情况,则不会触发无事件转换(因为它们不应该触发),但是状态机最终会在一个 no_transition 调用,它本质上是一个包罗万象的意外错误处理程序。这还需要入侵我希望避免的库代码。
但在我做任何事情之前,我想看看其他人是否发现了这个。或者给我关于在哪里获得帮助的建议。
更新: 显然,我公司使用的 Boost Library 版本是 1.44,并且在该版本中存在延迟事件处理的错误。它已在 1.46.1 中修复。
【问题讨论】:
-
没错,1.44 中存在一个错误,正如您所发现的,它已在 1.46 中修复。如果由于某种原因你被 1.44 卡住了,你可以通过添加到任何状态定义中来强制激活延迟事件来解决这个错误: typedef mpl::vector* any event */> deferred_events;