如何使用状态机处理多个状态?

时间:2017-07-09 22:00:40

标签: state-machine

我开始使用状态机实现系统。但我发现我怀疑状态机是正确的方法。

例如:我有四种状态:

(空闲,通电,断电,工作)

以及其他两个州:

(生产,测试)

上电和断电在生产和测试状态下表现不同......

如果我确实有更多的州,那么国家组合会爆炸......

如何通过状态机解决这个问题?

5 个答案:

答案 0 :(得分:1)

由于实际用例非常模糊,但有点难以回答,但这里有一些可能的技巧:

  1. 为Production + Powerup,Test + Powerup,Production + Powerdown,Test + Powerdown创建单独的状态。根据状态组合的复杂性和数量,这可能会很快爆炸。
  2. 优点:直截了当。

    缺点:混乱,不能很好地扩展,如果某些状态逻辑在实例之间共享,则会涉及一些复制意义(因此,不太可维护)

    1. 使用分层状态机(HFSM),也就是说,如果您可以在各个状态组之间定义某种层次关系,则特定状态的实现将是其自身的状态机。
    2. 因此,在您的示例中,您将拥有一个生产/测试状态机,并且每个机器都将在内部实现它自己的空闲/加电/掉电/工作状态机。

      如果你认为这一点,这实际上是选项1的更简洁的实现。

      优点:比选项1更具可读性

      缺点:假设子状态应该共享一些常见的登录,仍然会涉及复制粘贴

      1. 拥有2台并行状态机,一台处理生产/测试状态,另一台处理空闲/上电/掉电/工作状态,并使用某种黑板或共享内存在机器之间进行通信。
      2. 在您的示例中,您的代理或系统将是上述状态机的容器并依次处理它们。生产/测试机器会将一些状态写入另一台机器将读取的共享内存,并相应地分支它的状态逻辑。

        优点:可以在不同状态之间共享代码

        缺点:可以在不同的州之间共享代码......好的,严肃的,强调共享代码并不总是一个好主意(但这是一个完整的其他哲学讨论)只需确保正确评估共享代码的数量与唯一代码或路径的数量,这样您就不会得到一个基本上包含2个完全独立的代码路径的庞大类

        1. 我知道它已被授予,但请考虑FSM是否是在应用程序中表示状态和执行的正确方法。再一次,没有足够的背景来深入研究这一点,而这一点就是一个哲学辩论 - 但同时也要对其他解决方案持开放态度。

答案 1 :(得分:1)

您的状态机“爆炸”的感觉在传统的“扁平”FSM中非常典型(实际上它通常被称为“状态转换爆炸”现象)。解决方法是使用分层状态机(HSM),它专门抵消传统FSM的“爆炸”。基本上,HSM允许您将具有相似行为的状态组合在一起(在更高级别的超级状态内),从而重用相关状态之间的共同行为。这是一个非常强大的概念,可以带来更加优雅和一致的设计。要了解有关分层状态机的更多信息,请阅读文章"Introduction to Hierarchical State Machines"

答案 2 :(得分:0)

状态机可以与另一个共享信号。因此,指示prod或dev的状态机可以向另一个发送信号。

实际上,如果状态机上只有2个状态,则可以使用变量来实现此目的。因此,您将拥有一个状态机,它将根据变量的值执行不同的工作。

答案 3 :(得分:0)

我会将生产'分类。和'测试'作为模式,而不是国家。它仍然有些混乱,但在我看来,区别很重要。

switch(state)
{
case powerup:
    switch(mode)
    {
    case test:
        test_powerup_stuff();
        break;
    case production:
        production_powerup_stuff();
        break;
    default:
        break;
    }
    break;
case powerdown:
    switch(mode)
    {
    case test:
        test_powerdown_stuff();
        break;
    case production:
        production_powerdown_stuff();
        break;
    default:
        break;
    }
    break;
case idle:
    do_idle_stuff();
    break;
case work:
    do_work_stuff();
    break;
default:
    state = powerdown;
    break;
}

答案 4 :(得分:0)

是否需要两个相同状态机模型的实例?一个用于生产,一个用于测试?

另一种方法是生产和测试可以是单个机器的正交区域