状态机将事件推送到其自己的事件队列

时间:2013-06-22 17:05:13

标签: events transitions fsm state-machine

我目前正在研究分层状态机(UML状态机,状态图等),我不清楚以下内容:

在转换期间将事件推送到机器自己的事件队列,并且从有效状态推送事件队列,如果是,是否在实践中安全使用或是否应该避免?这样做是否有某些影响(至少是实施怪癖,正交区域发挥作用时的问题,或类似情况)?

我将用两台虚拟机器说明问题:

  1. 以下机器将处于状态A,等待事件A_to_B,然后通过将事件作为转换操作调度进入无限循环:

          +-----+                    +-----+                    +-----+
          |  A  |  A_to_B /          |  B  |  B_to_C /          |  C  |
          |-----|   dispatch B_to_C  |-----|   dispatch C_to_A  |-----|
    O---->|     +------------------->|     +------------------->|     |
          |     |                    |     |                    |     |
          +-----+                    +-----+                    +-----+
             ^                                C_to_A /             |
             |                                 dispatch A_to_B     |
             +-----------------------------------------------------+
    
  2. 通过将事件作为输入操作调度,以下机器将立即进入无限循环:

          +-------------------+           +-------------------+           +-----+
          |         A         |           |         B         |           |  C  |
          |-------------------|  A_to_B   |-------------------|  B_to_C   |-----|
    O---->| on entry:         +---------->| on entry:         +---------->|     |
          |  dispatch A_to_B  |           |  dispatch B_to_C  |           |     |
          |                   |           |  dispatch C_to_A  |           |     |
          +-------------------+           +-------------------+           +-----+
             ^                                                               |
             |                                                   C_to_A      |
             +---------------------------------------------------------------+
    

1 个答案:

答案 0 :(得分:6)

状态机可以将事件发布到自己,但这有特殊用途,例如将更长的运行完成(RTC)步骤分解为更短的部分。您可能希望这样做以在您太长的RTC步骤之间启用系统中其他状态机(或更常见的活动对象)的调度。

具体到您的示例,我会尽量避免在这种情况下向自己发布事件。通常我会看到人们在将状态图与流程图混淆时执行此操作。状态图需要事件从一个状态转换到另一个状态。在完成框中指定的计算后,流程图自动从一个处理框转换到另一个处理框。显然,当您向自己发布事件时,您将状态图转换为流程图。所以,你真的需要一个流程图,而不是状态图,因为你真的不需要等待任何事情。你继续全速处理。

您也可以这样查看。事件的目的是为状态机提供新信息。这就是状态机“学习”的方式。但是当你向自己发布事件时,你不会获得任何新知识。您需要的所有知识都已经由原始的“真实”事件提供。因此,您有足够的信息在一次转换中执行所有这些处理,而不是将其分布在许多“状态”中,这实际上是这种冗长处理的阶段。