【状态机】基于Linux C++的一种成熟的带线程控制的状态机
1. 头文件 ThreadedStateMachine.h
#ifndef THREADED_STATE_MACHINE_H
#define THREADED_STATE_MACHINE_H
#include <iostream>
#include <map>
#include <functional>
#include <string>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <atomic>
class ThreadedStateMachine {
public:
enum class State {
IDLE,
RUNNING,
PAUSED,
STOPPED
};
enum class Event {
START,
PAUSE,
RESUME,
STOP,
TICK,
SHUTDOWN
};
using TransitionHandler = std::function<void()>;
using StateHandler = std::function<void()>;
// 构造函数和析构函数
ThreadedStateMachine();
~ThreadedStateMachine();
// 禁止拷贝和赋值
ThreadedStateMachine(const ThreadedStateMachine&) = delete;
ThreadedStateMachine& operator=(const ThreadedStateMachine&) = delete;
// 公共接口
bool start();
void stop();
bool postEvent(Event event);
State getCurrentState() const;
bool isRunning() const;
// 状态和事件字符串转换
std::string stateToString(State state) const;
std::string eventToString(Event event) const;
private:
// 状态机配置
void setupTransitions();
void setupStateHandlers();
// 线程函数
void stateMachineLoop();
void eventProcessingLoop();
void processEvent(Event event);
// 转换处理函数
void onStart();
void onPause();
void onResume();
void onStop();
void onShutdown();
// 状态进入函数
void onEnterIdle();
void onEnterRunning();
void onEnterPaused();
void onEnterStopped();
// 状态退出函数
void onExitIdle();
void onExitRunning();
void onExitPaused();
void onExitStopped();
// 状态处理函数(在TICK事件中执行)
void processIdle();
void processRunning();
void processPaused();
void processStopped();
private:
// 状态机状态
State currentState;
std::atomic<bool> running;
std::atomic<bool> shutdownRequested;
// 线程相关
std::thread stateMachineThread;
std::thread eventProcessorThread;
std::mutex eventMutex;
std::condition_variable eventCV;
std::queue<Event> eventQueue;
// 状态保护
mutable std::mutex stateMutex;
// 状态转换表和处理函数
std::map<std::pair<State, Event>, std::pair<State, TransitionHandler>> transitions;
std::map<State, StateHandler> stateEnterHandlers;
std::map<State, StateHandler> stateExitHandlers;
std::map<State, StateHandler> stateProcessHandlers;
};
#endif // THREADED_STATE_MACHINE_H
2. 源文件 ThreadedStateMachine.cpp
#include "ThreadedStateMachine.h"
ThreadedStateMachine::ThreadedStateMachine()
: currentState(State::IDLE)
, running(false)
, shutdownRequested(false) {
setupTransitions();
setupStateHandlers();
}
ThreadedStateMachine::~ThreadedStateMachine() {
stop();
}
void ThreadedStateMachine::setupTransitions() {
// 定义状态转换表
transitions[{State::IDLE, Event::START}] = {State::RUNNING, [this]() { onStart(); }};
transitions[{State::RUNNING, Event::PAUSE}] = {State::PAUSED, [this]() { onPause(); }};
transitions[{State::RUNNING, Event::STOP}] = {State::STOPPED, [this]() { onStop(); }};
transitions[{State::PAUSED, Event::RESUME}] = {State::RUNNING, [this]() { onResume(); }};
transitions[{State::PAUSED, Event::STOP}] = {State::STOPPED, [this]() { onStop(); }};
transitions[{State::STOPPED, Event::START}] = {State::RUNNING, [this]() { onStart(); }};
// 为每个状态添加TICK事件处理
transitions[{State::IDLE, Event::TICK}] = {State::IDLE, [this]() { processIdle(); }};
transitions[{State::RUNNING, Event::TICK}] = {State::RUNNING, [this]() { processRunning(); }};
transitions[{State::PAUSED, Event::TICK}] = {State::PAUSED, [this]() { processPaused(); }};
transitions[{State::STOPPED, Event::TICK}] = {State::STOPPED, [this]() { processStopped(); }};
// 关机事件处理
transitions[{State::IDLE, Event::SHUTDOWN}] = {State::STOPPED, [this]() { onShutdown(); }};
transitions[{State::RUNNING, Event::SHUTDOWN}] = {State::STOPPED, [this]() { onShutdown(); }};
transitions[{State::PAUSED, Event::SHUTDOWN}] = {State::STOPPED, [this]() { onShutdown(); }};
transitions[{State::STOPPED, Event::SHUTDOWN}] = {State::STOPPED, [this]() { onShutdown(); }};
}
void ThreadedStateMachine::setupStateHandlers() {
// 状态进入处理函数
stateEnterHandlers[State::IDLE] = [this]() { onEnterIdle(); };
stateEnterHandlers[State::RUNNING] = [this]() { onEnterRunning(); };
stateEnterHandlers[State::PAUSED] = [this]() { onEnterPaused(); };
stateEnterHandlers[State::STOPPED] = [this]() { onEnterStopped(); };
// 状态退出处理函数
stateExitHandlers[State::IDLE] = [this]() { onExitIdle(); };
stateExitHandlers[State::RUNNING] = [this]() { onExitRunning(); };
stateExitHandlers[State::PAUSED] = [this]() { onExitPaused(); };
stateExitHandlers[State::STOPPED] = [this]() { onExitStopped(); };
}
bool ThreadedStateMachine::start() {
if (running) {
std::cout << "状态机已经在运行中" << std::endl;
return false;
}
running = true;
shutdownRequested = false;
// 启动状态机主线程
stateMachineThread = std::thread(&ThreadedStateMachine::stateMachineLoop, this);
// 启动事件处理线程
eventProcessorThread = std::thread(&ThreadedStateMachine::eventProcessingLoop, this);
std::cout << "状态机线程启动成功" << std::endl;
return true;
}
void ThreadedStateMachine::stop() {
if (!running) {
return;
}
std::cout << "正在停止状态机..." << std::endl;
shutdownRequested = true;
// 发送关机事件
postEvent(Event::SHUTDOWN);
// 唤醒事件处理线程
eventCV.notify_all();
// 等待线程结束
if (eventProcessorThread.joinable()) {
eventProcessorThread.join();
}
if (stateMachineThread.joinable()) {
stateMachineThread.join();
}
running = false;
std::cout << "状态机已完全停止" << std::endl;
}
bool ThreadedStateMachine::postEvent(Event event) {
if (!running || shutdownRequested) {
return false;
}
std::lock_guard<std::mutex> lock(eventMutex);
eventQueue.push(event);
eventCV.notify_one();
std::cout << "事件已发布: " << eventToString(event) << std::endl;
return true;
}
ThreadedStateMachine::State ThreadedStateMachine::getCurrentState() const {
std::lock_guard<std::mutex> lock(stateMutex);
return currentState;
}
bool ThreadedStateMachine::isRunning() const {
return running;
}
std::string ThreadedStateMachine::stateToString(State state) const {
switch (state) {
case State::IDLE: return "IDLE";
case State::RUNNING: return "RUNNING";
case State::PAUSED: return "PAUSED";
case State::STOPPED: return "STOPPED";
default: return "UNKNOWN";
}
}
std::string ThreadedStateMachine::eventToString(Event event) const {
switch (event) {
case Event::START: return "START";
case Event::PAUSE: return "PAUSE";
case Event::RESUME: return "RESUME";
case Event::STOP: return "STOP";
case Event::TICK: return "TICK";
case Event::SHUTDOWN: return "SHUTDOWN";
default: return "UNKNOWN";
}
}
void ThreadedStateMachine::stateMachineLoop() {
std::cout << "状态机主循环开始" << std::endl;
while (running && !shutdownRequested) {
// 生成TICK事件
postEvent(Event::TICK);
// 休眠一段时间
std::this_thread::sleep_for(std::chrono::milliseconds(500));
// 检查是否需要停止
if (getCurrentState() == State::STOPPED && shutdownRequested) {
break;
}
}
std::cout << "状态机主循环结束" << std::endl;
}
void ThreadedStateMachine::eventProcessingLoop() {
std::cout << "事件处理循环开始" << std::endl;
while (running && !shutdownRequested) {
Event event;
{
std::unique_lock<std::mutex> lock(eventMutex);
// 等待事件或超时
if (eventQueue.empty()) {
eventCV.wait_for(lock, std::chrono::milliseconds(100));
}
if (eventQueue.empty()) {
continue;
}
event = eventQueue.front();
eventQueue.pop();
}
// 处理事件
processEvent(event);
// 如果是关机事件,立即退出
if (event == Event::SHUTDOWN) {
break;
}
}
std::cout << "事件处理循环结束" << std::endl;
}
void ThreadedStateMachine::processEvent(Event event) {
auto key = std::make_pair(currentState, event);
auto it = transitions.find(key);
if (it != transitions.end()) {
State oldState = currentState;
State newState = it->second.first;
// 执行旧状态的退出函数
auto exitIt = stateExitHandlers.find(oldState);
if (exitIt != stateExitHandlers.end()) {
exitIt->second();
}
std::cout << "[线程" << std::this_thread::get_id() << "] "
<< "状态转换: " << stateToString(oldState)
<< " -> " << stateToString(newState)
<< " (事件: " << eventToString(event) << ")" << std::endl;
// 执行转换处理函数
it->second.second();
// 更新状态(线程安全)
{
std::lock_guard<std::mutex> lock(stateMutex);
currentState = newState;
}
// 执行新状态的进入函数
auto enterIt = stateEnterHandlers.find(newState);
if (enterIt != stateEnterHandlers.end()) {
enterIt->second();
}
} else {
std::cout << "[线程" << std::this_thread::get_id() << "] "
<< "无效转换: 当前状态 " << stateToString(currentState)
<< " 无法处理事件 " << eventToString(event) << std::endl;
}
}
void ThreadedStateMachine::onStart() {
std::cout << "执行启动逻辑..." << std::endl;
}
void ThreadedStateMachine::onPause() {
std::cout << "执行暂停逻辑..." << std::endl;
}
void ThreadedStateMachine::onResume() {
std::cout << "执行恢复逻辑..." << std::endl;
}
void ThreadedStateMachine::onStop() {
std::cout << "执行停止逻辑..." << std::endl;
}
void ThreadedStateMachine::onShutdown() {
std::cout << "执行关机逻辑..." << std::endl;
}
void ThreadedStateMachine::onEnterIdle() {
std::cout << ">>> 进入空闲状态" << std::endl;
}
void ThreadedStateMachine::onEnterRunning() {
std::cout << ">>> 进入运行状态" << std::endl;
}
void ThreadedStateMachine::onEnterPaused() {
std::cout << ">>> 进入暂停状态" << std::endl;
}
void ThreadedStateMachine::onEnterStopped() {
std::cout << ">>> 进入停止状态" << std::endl;
}
void ThreadedStateMachine::onExitIdle() {
std::cout << "<<< 退出空闲状态" << std::endl;
}
void ThreadedStateMachine::onExitRunning() {
std::cout << "<<< 退出运行状态" << std::endl;
}
void ThreadedStateMachine::onExitPaused() {
std::cout << "<<< 退出暂停状态" << std::endl;
}
void ThreadedStateMachine::onExitStopped() {
std::cout << "<<< 退出停止状态" << std::endl;
}
void ThreadedStateMachine::processIdle() {
static int counter = 0;
std::cout << "[IDLE] 等待启动命令... (" << ++counter << ")" << std::endl;
}
void ThreadedStateMachine::processRunning() {
static int counter = 0;
std::cout << "[RUNNING] 正在处理任务... (" << ++counter << ")" << std::endl;
// 模拟一些工作
if (counter % 3 == 0) {
std::cout << "[RUNNING] 完成一批任务" << std::endl;
}
}
void ThreadedStateMachine::processPaused() {
static int counter = 0;
std::cout << "[PAUSED] 系统暂停中... (" << ++counter << ")" << std::endl;
}
void ThreadedStateMachine::processStopped() {
static int counter = 0;
std::cout << "[STOPPED] 系统已停止 (" << ++counter << ")" << std::endl;
}
3. 测试文件 main.cpp
#include "ThreadedStateMachine.h"
#include <random>
#include <vector>
// 测试函数
int main() {
std::cout << "=== 线程化状态机测试 ===" << std::endl;
ThreadedStateMachine sm;
// 启动状态机
if (!sm.start()) {
std::cerr << "启动状态机失败" << std::endl;
return -1;
}
// 等待状态机初始化
std::this_thread::sleep_for(std::chrono::seconds(1));
// 创建多个控制线程来发送事件
std::vector<std::thread> controlThreads;
// 线程1:正常流程控制
controlThreads.emplace_back([&sm]() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1000, 3000);
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(dis(gen)));
switch (i % 4) {
case 0:
sm.postEvent(ThreadedStateMachine::Event::START);
break;
case 1:
sm.postEvent(ThreadedStateMachine::Event::PAUSE);
break;
case 2:
sm.postEvent(ThreadedStateMachine::Event::RESUME);
break;
case 3:
sm.postEvent(ThreadedStateMachine::Event::STOP);
break;
}
}
});
// 线程2:随机事件
controlThreads.emplace_back([&sm]() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(500, 2000);
std::uniform_int_distribution<> eventDis(0, 3);
for (int i = 0; i < 8; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(dis(gen)));
ThreadedStateMachine::Event event;
switch (eventDis(gen)) {
case 0: event = ThreadedStateMachine::Event::START; break;
case 1: event = ThreadedStateMachine::Event::PAUSE; break;
case 2: event = ThreadedStateMachine::Event::RESUME; break;
case 3: event = ThreadedStateMachine::Event::STOP; break;
default: event = ThreadedStateMachine::Event::START; break;
}
sm.postEvent(event);
}
});
// 等待控制线程完成
for (auto& thread : controlThreads) {
thread.join();
}
// 让状态机再运行一段时间
std::this_thread::sleep_for(std::chrono::seconds(3));
// 优雅停止状态机
std::cout << "准备关闭状态机..." << std::endl;
sm.stop();
std::cout << "测试完成" << std::endl;
return 0;
}
4. CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(ThreadedStateMachineDemo)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 添加可执行文件
add_executable(state_machine_demo
ThreadedStateMachine.cpp
main.cpp
)
# 设置编译器选项
target_compile_options(state_machine_demo PRIVATE -Wall -Wextra -pthread)
# 设置链接选项
target_link_libraries(state_machine_demo pthread)
5. 编译和运行
# 创建构建目录
mkdir build
cd build
# 配置项目
cmake ..
# 编译
make
# 运行
./state_machine_demo
文件结构说明
threaded_state_machine/
├── ThreadedStateMachine.h # 头文件 - 类声明和接口
├── ThreadedStateMachine.cpp # 源文件 - 类实现
├── main.cpp # 测试程序
└── CMakeLists.txt # 构建配置
主要改进点
-
清晰的接口分离:头文件只暴露公共接口,隐藏实现细节
-
防止拷贝:明确禁止拷贝构造和赋值操作
-
线程安全:使用适当的同步原语保护共享数据
-
资源管理:在析构函数中自动清理资源
-
模块化设计:每个函数职责单一,便于维护和测试
这样的设计使得状态机可以作为一个独立的模块被其他项目引用和使用。

浙公网安备 33010602011771号