第一章 状态机入门:什么是状态机

大家好,我是你们的老朋友。今天咱们聊聊状态机。

说实话,我第一次接触状态机是在大学做数字电路实验的时候。当时老师扔给我一个交通灯控制的题目,我盯着面包板上那一堆逻辑门芯片,完全不知道从哪下手。后来师兄跟我说了句:「你想想看,红绿灯不就是几个状态来回切换吗?」——嗯,这句话点醒了我。

什么是状态机?

状态机,英文叫 Finite State Machine(FSM),翻译过来就是「有限状态机」。说白了,它就是一个会记住自己当前处于什么状态,并且能根据输入决定下一步该去哪里的系统。

我习惯用一个比喻来解释:状态机就像一台自动售货机。

  • 它当前的状态是「等待投币」
  • 你投了一块钱,这是事件
  • 它收到事件后,转移到「已投币1元」状态
  • 你再选商品,它又转移到「出货中」状态

你看,整个过程就是:当前状态 + 输入事件 → 下一个状态。就这么简单。

核心公式:状态机 = 状态 + 事件 + 转移规则

状态机的基本概念

咱们把三个核心概念拆开来讲。

1. 状态(State)

状态就是系统在某个时刻的「快照」。比如一个门,要么是「开」要么是「关」。一个电梯,要么在「1楼」要么在「2楼」。

我在项目中遇到过一个问题:有人把状态定义得太细了。比如一个通信协议,他定义了20多个状态,结果代码写得自己都看不懂。我的建议是:状态数量控制在5~10个以内,超过这个数,你就该考虑是不是设计有问题了。

2. 事件(Event)

事件是触发状态变化的东西。可以是外部输入,也可以是内部信号。

举个例子:

  • 按键按下 → 事件
  • 定时器超时 → 事件
  • 数据包到达 → 事件
  • 温度超过阈值 → 事件

注意一点:不是所有事件都会导致状态转移。比如你在「等待投币」状态时,按「取消」按钮,可能什么都不会发生。这叫「事件被忽略」。

3. 转移(Transition)

转移就是「从状态A到状态B」的路径。每条转移都包含三个要素:

要素 说明 例子
源状态 当前在哪个状态 等待投币
触发事件 什么导致了转移 收到1元硬币
目标状态 转移到哪里去 已投币1元

小技巧:我习惯在画状态图时,用箭头标注「事件/条件」。比如「投币/余额≥2元 → 允许购买」。这样一目了然。

状态机的应用场景

你可能会问:这东西到底用在哪?我告诉你,到处都是。

硬件设计领域

  • CPU的指令译码器:每个指令周期就是一个状态机
  • UART通信协议:发送和接收都有明确的状态序列
  • LCD显示屏驱动:初始化、刷新、休眠等状态切换

软件工程领域

  • 游戏角色的AI:巡逻、追击、攻击、逃跑
  • 网络协议栈:TCP的三次握手就是典型的状态机
  • 工作流引擎:审批流程的「待审批→已通过→已驳回」

我记得有一次帮朋友调试一个智能门锁的固件。问题出在:用户输入密码时,如果中途按了取消键,系统就卡死了。我一看代码,发现他根本没处理「取消」这个事件。这就是典型的状态机设计不完整——你想想看,任何系统都可能遇到意外输入,不处理就是bug。

避坑指南:我曾经犯过一个错误——只考虑了「正常流程」的状态转移,忽略了异常情况。比如超时、错误输入、电源波动等。后来我养成了一个习惯:每个状态都要问自己三个问题——

  1. 这个状态下,哪些事件是合法的?
  2. 非法事件来了怎么办?
  3. 如果卡在这个状态出不去,有没有超时保护?

本章知识体系

下面这张图,是我用SVG画的本章核心逻辑。你看一眼就能明白状态机的骨架。

状态机核心概念关系图 状态A (等待中) 状态B (工作中) 事件1(启动) 事件2(完成) 事件3(忽略) 状态机三要素 ● 状态:系统在某一时刻的稳定情况 ● 事件:触发状态变化的外部或内部信号 ● 转移:从当前状态到下一个状态的路径规则

这张图里,状态A和状态B通过事件连接。注意那个自循环箭头——它表示「事件3来了,但状态不变」。这在真实系统中很常见,比如你在等待状态时收到一个无效指令,系统应该忽略它,而不是崩溃。

小结

状态机不是什么高深莫测的东西。它就是一套规则:告诉我你现在在哪,发生了什么,我就能告诉你下一步去哪。

我刚开始学的时候,总觉得要背很多概念。后来发现,你只要记住三个词就够了:状态、事件、转移。剩下的,都是在这些基础上搭积木。

嗯,这一章就到这里。下一章咱们会动手画一个真正的状态图,到时候你就知道这东西有多好用了。

课后思考:你身边有没有什么设备或系统,可以用状态机来描述?试着画一画它的状态和转移。不用太复杂,三个状态就够。

可可精品资料库