第三章:状态机的进阶技巧
在前两章中,我们介绍了状态机的基本概念和简单实现方法。本章将深入探讨状态机的进阶技巧,包括状态机与事件驱动的结合、分层状态机设计、状态机的内存管理以及状态持久化与恢复等内容。这些技巧将帮助我们构建更加复杂、灵活和健壮的状态机系统。
3.1 状态机与事件驱动
事件驱动编程是一种常见的编程范式,特别适合与状态机结合使用。在事件驱动的状态机中,系统不是主动轮询状态和条件,而是被动地等待事件发生,然后根据当前状态和接收到的事件执行相应的动作。
3.1.1 事件队列
事件驱动状态机的核心是事件队列,它用于存储待处理的事件。事件可以来自多个源,如硬件中断、定时器、用户输入或其他任务。
// 事件结构体
typedef struct {
EventType type; // 事件类型
void *data; // 事件数据(可选)
uint32_t timestamp; // 事件时间戳
} Event;
// 事件队列结构体
typedef struct {
Event *events; // 事件数组
uint16_t capacity; // 队列容量
uint16_t size; // 当前事件数量
uint16_t front; // 队列头索引
uint16_t rear; // 队列尾索引
} EventQueue;
// 初始化事件队列
bool event_queue_init(EventQueue *queue, uint16_t capacity) {
if (queue == NULL || capacity == 0) {
return false;
}
queue->events = (Event *)malloc(capacity * sizeof(Event));
if (queue->events == NULL) {
return false; // 内存分配失败
}
queue->capacity = capacity;
queue->size = 0;
queue->front = 0;
queue->rear = 0;
return true;
}
// 销毁事件队列
void event_queue_destroy(EventQueue *queue) {
if (queue == NULL || queue->events == NULL) {
return;
}
free(queue->events);
queue->events = NULL;
queue->capacity = 0;
queue->size = 0;
queue->front = 0;
queue->rear = 0;
}
// 向队列添加事件
bool event_queue_push(EventQueue *queue, Event *event) {
if (queue == NULL || queue->events == NULL || event == NULL) {
return false;
}
// 检查队列是否已满
if (queue->size >= queue->capacity) {
return false; // 队列已满
}
// 添加事件到队列尾部
queue->events[queue->rear] = *event;
queue->rear = (queue->rear + 1) % queue->capacity; // 循环队列
queue->size++;
return true;
}
// 从队列获取事件
bool event_queue_pop(EventQueue *queue, Event *event) {
if (queue == NULL || queue->events == NULL || event == NULL) {
return false;
}
// 检查队列是否为空
if (queue->size == 0) {
return false; // 队列为空
}
// 获取队列头部事件
*event = queue->events[queue->front];
queue->front = (queue->front + 1) % queue->capacity; // 循环队列
queue->size--;
return true;
}
3.1.2 事件驱动状态机框架
下面是一个基于事件驱动的状态机框架:
// 状态机结构体
typedef struct {
State current_state; // 当前状态
EventQueue event_queue; // 事件队列
bool running; // 运行标志
} StateMachine;
// 状态处理函数类型
typedef State (*StateHandler)(StateMachine *sm, Event *event);
// 状态处理函数映射表
StateHandler state_handlers[STATE_MAX] = {
handle_state_idle,
handle_state_active,
handle_state_paused,
handle_state_error
// 其他状态处理函数...
};
// 初始化状态机
bool state_machine_init(StateMachine *sm, State initial_state, uint16_t queue_capacity) {
if (sm == NULL) {
return false;
}
sm->current_state = initial_state;
sm->running = false;
// 初始化事件队列
if (!event_queue_init(&sm->event_queue, queue_capacity)) {
return false;
}
return true;
}
// 销毁状态机
void state_machine_destroy(StateMachine *sm) {
if (sm == NULL) {
return;
}
sm->running = false;
event_queue_destroy(&sm->event_queue);
}
// 向状态机发送事件
bool state_machine_send_event(StateMachine *sm, Event *event) {
if (sm == NULL || event == NULL) {
return false;
}
// 添加事件到队列
return event_queue_push(&sm->event_queue, event);
}
// 状态机主循环
void state_machine_run(StateMachine *sm) {
if (sm == NULL) {
return;
}
sm->running = true;
while (sm->running) {
Event event;
// 从队列获取事件
if (event_queue_pop(&sm->event_queue, &event)) {
// 调用当前状态的处理函数
if (sm->current_state < STATE_MAX && state_handlers[sm->current_state] != NULL) {
State next_state = state_handlers[sm->current_state](sm, &event);
// 如果状态发生变化
if (next_state != sm->current_state) {
// 执行状态转换
sm->current_state = next_state;
}
}
} else {
// 队列为空,可以休眠一段时间或让出CPU
sleep_or_yield();
}
}
}
// 停止状态机
void state_machine_stop(StateMachine *sm) {
if (sm == NULL) {
return;
}
sm->running = false;
}
3.1.3 状态处理函数示例
// 空闲状态处理函数
State handle_state_idle(StateMachine *sm, Event *event) {
switch (event->type) {
case EVENT_START:
printf("Idle state: Received START event, transitioning to ACTIVE\n");
// 执行从IDLE到ACTIVE的转换动作
return STATE_ACTIVE;
case EVENT_ERROR:
printf("Idle state: Received ERROR event, transitioning to ERROR\n");
// 执行从IDLE到ERROR的转换动作
return STATE_ERROR;
default:
printf("Idle state: Unhandled event %d\n", event->type);
return STATE_IDLE; // 保持当前状态
}
}
// 活动状态处理函数
State handle_state_active(StateMachine *sm, Event *event) {
switch (event->type) {
case EVENT_PAUSE:
printf("Active state: Received PAUSE event, transitioning to PAUSED\n");
// 执行从ACTIVE到PAUSED的转换动作
return STATE_PAUSED;
case EVENT_STOP:
printf("Active state: Received STOP event, transitioning to IDLE\n");
// 执行从ACTIVE到IDLE的转换动作
return STATE_IDLE;
case EVENT_ERROR:
printf("Active state: Received ERROR event, transitioning to ERROR\n");
// 执行从ACTIVE到ERROR的转换动作
return STATE_ERROR;
default:
printf("Active state: Unhandled event %d\n", event->type);
return STATE_ACTIVE; // 保持当前状态
}
}
// 其他状态处理函数...
3.1.4 事件生成示例
事件可以从多个源生成,例如:
// 定时器中断处理函数
void timer_interrupt_handler(void) {
// 创建定时器事件
Event timer_event;
timer_event.type = EVENT_TIMER;
timer_event.data = NULL;
timer_event.timestamp = get_system_time();
// 发送事件到状态机
state_machine_send_event(&global_state_machine, &timer_event);
}
// 按钮中断处理函数
void button_interrupt_handler(uint8_t button_id) {
// 创建按钮事件
Event button_event;
button_event.type = EVENT_BUTTON_PRESS;
// 分配并设置按钮数据
ButtonData *button_data = (ButtonData *)malloc(sizeof(ButtonData));
if (button_data != NULL) {
button_data->button_id = button_id;
button_data->press_time = get_system_time();
button_event.data = button_data;
} else {
button_event.data = NULL;
}
button_event.timestamp = get_system_time();
// 发送事件到状态机
state_machine_send_event(&global_state_machine, &button_event);
}
3.1.5 事件驱动状态机的优缺点
优点:
- 响应性:能够快速响应异步事件
- 资源效率:在没有事件时可以休眠,节省CPU资源
- 解耦:事件生成和处理逻辑分离,提高模块化
- 可扩展性:容易添加新的事件类型和处理逻辑
缺点:
- 复杂性:比简单轮询更复杂,需要额外的队列管理
- 内存开销:事件队列需要额外的内存
- 调试难度:异步事件处理可能增加调试难度
- 优先级处理:基本实现不支持事件优先级,可能需要额外设计
3.2 分层状态机设计
随着系统复杂度增加,状态数量可能会爆炸性增长。分层状态机(Hierarchical State Machine,HSM)通过引入状态层次结构,有效地减少状态数量,提高状态机的可管理性。
3.2.1 分层状态机的概念
在分层状态机中,状态可以包含子状态,形成层次结构。当一个事件在当前状态无法处理时,会沿着状态层次向上传递,直到找到能处理该事件的父状态。
分层状态机的主要特点:
- 状态继承:子状态继承父状态的行为
- 事件冒泡:未处理的事件向上传递
- 转换层次:可以在不同层次间进行状态转换
3.2.2 分层状态机的C语言实现
// 状态ID定义
typedef enum {
// 顶层状态
STATE_TOP = 0, // 虚拟顶层状态
STATE_OPERATIONAL,
STATE_FAULT,
// STATE_OPERATIONAL的子状态
STATE_IDLE,
STATE_ACTIVE,
STATE_SUSPENDED,
// STATE_ACTIVE的子状态
STATE_INITIALIZING,
STATE_RUNNING,
STATE_FINALIZING,
// STATE_FAULT的子状态
STATE_RECOVERABLE_FAULT,
STATE_FATAL_FAULT,
STATE_MAX
} StateId;
// 状态处理结果
typedef enum {
HANDLED, // 事件已处理
NOT_HANDLED, // 事件未处理,应传递给父状态
TRANSITION, // 状态转换
SUPER // 获取父状态
} StateResult;
// 状态处理函数类型
typedef StateResult (*StateHandler)(StateMachine *sm, Event *event);
// 状态结构体
typedef struct {
StateId id; // 状态ID
StateHandler handler; // 状态处理函数
StateId parent_id; // 父状态ID
} State;
// 状态表
const State state_table[STATE_MAX] = {
{
STATE_TOP, handle_state_top, STATE_TOP}, // 顶层状态是自己的父状态
{
STATE_OPERATIONAL, handle_state_operational, STATE_TOP},
{
STATE_FAULT, handle_state_fault, STATE_TOP},
{
STATE_IDLE, handle_state_idle, STATE_OPERATIONAL},
{
STATE_ACTIVE, handle_state_active, STATE_OPERATIONAL},
{
STATE_SUSPENDED, handle_state_suspended, STATE_OPERATIONAL},
{
STATE_INITIALIZING, handle_state_initializing, STATE_ACTIVE},
{
STATE_RUNNING, handle_state_running, STATE_ACTIVE},
{
STATE_FINALIZING, handle_state_finalizing, STATE_ACTIVE},
{
STATE_RECOVERABLE_FAULT, handle_state_recoverable_fault, STATE_FAULT},
{
STATE_FATAL_FAULT, handle_state_fatal_fault, STATE_FAULT}
};
// 分层状态机结构体
typedef struct {
StateId current_state; // 当前状态ID
EventQueue event_queue; // 事件队列
bool running; // 运行标志
} HierarchicalStateMachine;
// 初始化分层状态机
bool hsm_init(HierarchicalStateMachine *hsm, StateId initial_state, uint16_t queue_capacity) {
if (hsm == NULL || initial_state >= STATE_MAX) {
return false;
}
hsm->current_state = initial_state;
hsm->running = false;
// 初始化事件队列
if (!event_queue_init(&hsm->event_queue, queue_capacity)) {
return false;
}
// 执行初始状态的入口动作
Event entry_event;
entry_event.type = EVENT_ENTRY;
entry_event.data = NULL;
entry_event.timestamp = get_system_time();
hsm_dispatch(hsm, &entry_event);
return true;
}
// 分发事件到状态处理函数
void hsm_dispatch(HierarchicalStateMachine *hsm, Event *event) {
if (hsm == NULL || event == NULL || hsm->current_state >= STATE_MAX) {
return;
}
StateId state_id = hsm->current_state;
StateResult result;
// 尝试在当前状态及其父状态链中处理事件
do {
// 获取状态处理函数
StateHandler handler = state_table[state_id].handler;
if (handler == NULL) {
break;
}
// 调用状态处理函数
result = handler(hsm, event);
// 根据处理结果执行相应操作
switch (result) {
case HANDLED:
return; // 事件已处理,结束
case NOT_HANDLED:
// 事件未处理,尝试父状态
state_id = state_table[state_id].parent_id;
break;
case TRANSITION:
// 状态转换,结束当前处理
return;
case SUPER:
// 获取父状态,继续处理
state_id = state_table[state_id].parent_id;
break;
}
} while (state_id != STATE_TOP); // 直到达到顶层状态
}
// 执行状态转换
void hsm_transition(HierarchicalStateMachine *hsm, StateId target_state) {
if (hsm == NULL || target_state >= STATE_MAX) {
return;
}
StateId source_state = hsm->current_state;
StateId source_path[STATE_MAX];
StateId target_path[STATE_MAX];
int source_depth = 0;
int target_depth = 0;
// 构建源状态路径(从当前状态到顶层状态)
StateId state_id = source_state;
while (state_id != STATE_TOP) {
source_path[source_depth++] = state_id;
state_id = state_table[state_id].parent_id;
}
// 构建目标状态路径(从目标状态到顶层状态)
state_id = target_state;
while (state_id != STATE_TOP) {
target_path[target_depth++] = state_id;
state_id = state_table[state_id].parent_id;

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



