一、单例模式
单例模式(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)。
性能提升
(2)行为一致性:
缺点:
(1)扩展性差:缺乏抽象层,难以通过继承扩展功能(违反开闭原则)。
(2)生命周期问题:静态实例长期占用内存,若未被利用则浪费资源。
1031