• 正文
  • 相关推荐
申请入驻 产业图谱

单例模式:嵌入式系统全局状态一致性的守护者

06/25 17:25
1031
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

一、单例模式

单例模式(Singleton Pattern)确保一个类仅有一个实例,并提供全局访问点。

单例模式核心结构图:

结构通常包括:

    一个私有静态实例(指向自身的指针)一个私有构造函数(防止外部创建实例)一个公共的静态方法(用于获取唯一实例)

嵌入式系统中,该模式尤其适用于:

全局状态

    • :系统配置、错误日志

硬件外设管理

资源池

    • :内存池、连接池

核心管理器

嵌入式设计要点:

线程安全

    • :需通过关中断、互斥锁保护临界区(尤其在RTOS中)。

无动态内存

    :优先静态分配实例,避免堆内存碎片。

二、嵌入式应用案例

一个远程监控系统的系统状态维护。

非单例模式

    • :每个模块(传感器模块、控制模块、通信模块)各自维护系统状态,导致:

      • 温度传感器认为系统正常但控制模块检测到故障状态不一致引发危险操作

单例模式:建立中央控制台(唯一实例),所有模块通过它访问系统状态,确保全局决策一致。

1、代码实现:

C语言:

#include <stdio.h>
#include <pthread.h>

// 全局状态结构体
typedefstruct {
    int system_mode; 
    int error_code;   
    unsignedlong operation_count;  
} SystemState;

// 单例状态管理器
typedefstruct {
    SystemState state;
    pthread_mutex_t lock;
} StateManager;

// 全局单例实例
static StateManager* instance = NULL;

// 获取单例实例(线程安全)
StateManager* get_state_manager() {
    if (instance == NULL) {
        // 创建互斥锁
        staticpthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
        pthread_mutex_lock(&init_lock);
        
        if (instance == NULL) {
            static StateManager manager;
            manager.state.system_mode = 0;
            manager.state.error_code = 0;
            manager.state.operation_count = 0;
            pthread_mutex_init(&manager.lock, NULL);
            instance = &manager;
        }
        
        pthread_mutex_unlock(&init_lock);
    }
    return instance;
}

// 设置系统模式
void set_system_mode(int mode) {
    StateManager* manager = get_state_manager();
    pthread_mutex_lock(&manager->lock);
    manager->state.system_mode = mode;
    pthread_mutex_unlock(&manager->lock);
}

// 获取系统模式
int get_system_mode() {
    StateManager* manager = get_state_manager();
    pthread_mutex_lock(&manager->lock);
    int mode = manager->state.system_mode;
    pthread_mutex_unlock(&manager->lock);
    return mode;
}

// 报告错误
void report_error(int error_code) {
    StateManager* manager = get_state_manager();
    pthread_mutex_lock(&manager->lock);
    manager->state.error_code = error_code;
    pthread_mutex_unlock(&manager->lock);
}

// 增加操作计数
void increment_operation_count() {
    StateManager* manager = get_state_manager();
    pthread_mutex_lock(&manager->lock);
    manager->state.operation_count++;
    pthread_mutex_unlock(&manager->lock);
}

// 打印系统状态
void print_system_state() {
    StateManager* manager = get_state_manager();
    pthread_mutex_lock(&manager->lock);
    
    printf("n=== 系统状态 ===n");
    printf("当前模式: %sn", 
           manager->state.system_mode == 0 ? "正常模式" :
           manager->state.system_mode == 1 ? "维护模式" : "紧急模式");
    printf("错误代码: 0x%04Xn", manager->state.error_code);
    printf("操作计数: %lun", manager->state.operation_count);
    
    pthread_mutex_unlock(&manager->lock);
}

// 模拟传感器模块
void* sensor_module(void* arg) {
    printf("传感器启动...n");
    for (int i = 0; i < 3; i++) {
        increment_operation_count();
        printf("传感器检测中...n");
        sleep(1);
    }
    returnNULL;
}

// 模拟控制模块
void* control_module(void* arg) {
    printf("控制器启动...n");
    sleep(1);
    
    // 模拟检测到错误
    report_error(0xE1A2);
    set_system_mode(2);  // 进入紧急模式
    
    printf("控制器检测到严重错误!n");
    returnNULL;
}

int main() {
    printf("=== 控制系统启动 ===n");
    
    // 初始化状态管理器
    get_state_manager();
    print_system_state();
    
    // 创建模拟线程
    pthread_t sensor_thread, control_thread;
    pthread_create(&sensor_thread, NULL, sensor_module, NULL);
    pthread_create(&control_thread, NULL, control_module, NULL);
    
    // 等待线程完成
    pthread_join(sensor_thread, NULL);
    pthread_join(control_thread, NULL);
    
    // 打印最终状态
    print_system_state();
    
    printf("n=== 系统关闭 ===n");
    return0;
}

在C语言中,没有类的概念,因此我们通过静态全局变量和函数来模拟单例模式。

私有静态实例:静态全局指针static StateManager* instance = NULL;,它指向唯一的实例。而实例本身是在获取函数内部使用静态局部变量static StateManager manager;来创建的。这样,实例在程序运行期间只被初始化一次,并且通过指针返回。

私有构造函数:在C中,通过静态初始化或在获取函数内部初始化来实现。在get_state_manager()函数中,通过静态局部变量来创建实例,并只做一次初始化

公共的静态方法:get_state_manager()函数,它返回单例实例的指针。同时,我们还提供了其他操作状态的函数,如set_system_mode()get_system_mode()等,这些函数内部都会调用get_state_manager()来获取单例实例。

C++:

#include <iostream>
#include <mutex>
#include <thread>
#include <vector>

class StateManager {
private:
    struct State {
        int system_mode = 0;
        int error_code = 0;
        unsignedlong operation_count = 0;
    } state;
    
    std::mutex mtx;  // 非静态成员锁,保护实例状态
    
    StateManager() = default;  // 私有构造函数

public:
    // 删除拷贝构造函数和赋值运算符
    StateManager(const StateManager&) = delete;
    voidoperator=(const StateManager&) = delete;

    // 使用局部静态变量实现线程安全的单例
    static StateManager& getInstance() {
        static StateManager instance;
        return instance;
    }
    
    void setSystemMode(int mode) {
        std::lock_guard<std::mutex> lock(mtx);
        state.system_mode = mode;
        state.operation_count++;
    }
    
    int getSystemMode() {
        std::lock_guard<std::mutex> lock(mtx);
        return state.system_mode;
    }
    
    void printState() {
        std::lock_guard<std::mutex> lock(mtx);
        std::cout << "Mode: " << state.system_mode 
                  << " | Errors: 0x" << std::hex << state.error_code
                  << " | Operations: " << std::dec << state.operation_count << "n";
    }
};

// 测试函数
void threadTask(int mode) {
    StateManager& manager = StateManager::getInstance();
    manager.setSystemMode(mode);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    manager.printState();
}

int main() {
    std::vector<std::thread> threads;
    
    // 创建多个线程测试线程安全
    for (int i = 1; i <= 5; ++i) {
        threads.emplace_back(threadTask, i);
    }
    
    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }

    // 主线程访问
    StateManager::getInstance().printState();
    return0;
}

2、优缺点

优点:

(1)资源高效性

内存节省

    • :仅一个实例,减少重复对象占用的RAM(关键于资源受限MCU)。

性能提升

    :避免频繁创建/销毁对象(如通信协议栈),降低CPU开销。

(2)行为一致性

    防止硬件状态冲突(如多任务同时配置UART波特率)。确保全局数据(如校准参数)唯一可信。
缺点:

(1)扩展性差:缺乏抽象层,难以通过继承扩展功能(违反开闭原则)。

(2)生命周期问题:静态实例长期占用内存,若未被利用则浪费资源。

三、嵌入式场景适用性总结

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

本公众号专注于嵌入式技术,包括但不限于C/C++、嵌入式、物联网、Linux等编程学习笔记,同时,公众号内包含大量的学习资源。欢迎关注,一同交流学习,共同进步!