• 正文
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

單例模式:嵌入式系統(tǒng)全局狀態(tài)一致性的守護(hù)者

3小時(shí)前
152
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

一、單例模式

單例模式(Singleton Pattern)確保一個(gè)類(lèi)僅有一個(gè)實(shí)例,并提供全局訪問(wèn)點(diǎn)。

單例模式核心結(jié)構(gòu)圖:

結(jié)構(gòu)通常包括:

    一個(gè)私有靜態(tài)實(shí)例(指向自身的指針)一個(gè)私有構(gòu)造函數(shù)(防止外部創(chuàng)建實(shí)例)一個(gè)公共的靜態(tài)方法(用于獲取唯一實(shí)例)

嵌入式系統(tǒng)中,該模式尤其適用于:

全局狀態(tài)

    • :系統(tǒng)配置、錯(cuò)誤日志

硬件外設(shè)管理

資源池

    • :內(nèi)存池、連接池

核心管理器

嵌入式設(shè)計(jì)要點(diǎn):

線(xiàn)程安全

    • :需通過(guò)關(guān)中斷、互斥鎖保護(hù)臨界區(qū)(尤其在RTOS中)。

無(wú)動(dòng)態(tài)內(nèi)存

    :優(yōu)先靜態(tài)分配實(shí)例,避免堆內(nèi)存碎片。

二、嵌入式應(yīng)用案例

一個(gè)遠(yuǎn)程監(jiān)控系統(tǒng)的系統(tǒng)狀態(tài)維護(hù)。

非單例模式

    • :每個(gè)模塊(傳感器模塊、控制模塊、通信模塊)各自維護(hù)系統(tǒng)狀態(tài),導(dǎo)致:

      • 溫度傳感器認(rèn)為系統(tǒng)正常但控制模塊檢測(cè)到故障狀態(tài)不一致引發(fā)危險(xiǎn)操作

單例模式:建立中央控制臺(tái)(唯一實(shí)例),所有模塊通過(guò)它訪問(wèn)系統(tǒng)狀態(tài),確保全局決策一致。

1、代碼實(shí)現(xiàn):

C語(yǔ)言:

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

// 全局狀態(tài)結(jié)構(gòu)體
typedefstruct?{
? ??int?system_mode;?
? ??int?error_code; ??
? ??unsignedlong?operation_count; ?
} SystemState;

// 單例狀態(tài)管理器
typedefstruct?{
? ? SystemState state;
? ??pthread_mutex_t?lock;
} StateManager;

// 全局單例實(shí)例
static?StateManager* instance =?NULL;

// 獲取單例實(shí)例(線(xiàn)程安全)
StateManager*?get_state_manager()?{
? ??if?(instance ==?NULL) {
? ? ? ??// 創(chuàng)建互斥鎖
? ? ? ??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;
}

// 設(shè)置系統(tǒng)模式
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);
}

// 獲取系統(tǒng)模式
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;
}

// 報(bào)告錯(cuò)誤
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);
}

// 增加操作計(jì)數(shù)
void?increment_operation_count()?{
? ? StateManager* manager = get_state_manager();
? ? pthread_mutex_lock(&manager->lock);
? ? manager->state.operation_count++;
? ? pthread_mutex_unlock(&manager->lock);
}

// 打印系統(tǒng)狀態(tài)
void?print_system_state()?{
? ? StateManager* manager = get_state_manager();
? ? pthread_mutex_lock(&manager->lock);
? ??
? ??printf("n=== 系統(tǒng)狀態(tài) ===n");
? ??printf("當(dāng)前模式: %sn",?
? ? ? ? ? ?manager->state.system_mode ==?0???"正常模式"?:
? ? ? ? ? ?manager->state.system_mode ==?1???"維護(hù)模式"?:?"緊急模式");
? ??printf("錯(cuò)誤代碼: 0x%04Xn", manager->state.error_code);
? ??printf("操作計(jì)數(shù): %lun", manager->state.operation_count);
? ??
? ? pthread_mutex_unlock(&manager->lock);
}

// 模擬傳感器模塊
void*?sensor_module(void* arg)?{
? ??printf("傳感器啟動(dòng)...n");
? ??for?(int?i =?0; i <?3; i++) {
? ? ? ? increment_operation_count();
? ? ? ??printf("傳感器檢測(cè)中...n");
? ? ? ? sleep(1);
? ? }
? ??returnNULL;
}

// 模擬控制模塊
void*?control_module(void* arg)?{
? ??printf("控制器啟動(dòng)...n");
? ? sleep(1);
? ??
? ??// 模擬檢測(cè)到錯(cuò)誤
? ? report_error(0xE1A2);
? ? set_system_mode(2); ?// 進(jìn)入緊急模式
? ??
? ??printf("控制器檢測(cè)到嚴(yán)重錯(cuò)誤!n");
? ??returnNULL;
}

int?main()?{
? ??printf("=== 控制系統(tǒng)啟動(dòng) ===n");
? ??
? ??// 初始化狀態(tài)管理器
? ? get_state_manager();
? ? print_system_state();
? ??
? ??// 創(chuàng)建模擬線(xiàn)程
? ??pthread_t?sensor_thread, control_thread;
? ? pthread_create(&sensor_thread,?NULL, sensor_module,?NULL);
? ? pthread_create(&control_thread,?NULL, control_module,?NULL);
? ??
? ??// 等待線(xiàn)程完成
? ? pthread_join(sensor_thread,?NULL);
? ? pthread_join(control_thread,?NULL);
? ??
? ??// 打印最終狀態(tài)
? ? print_system_state();
? ??
? ??printf("n=== 系統(tǒng)關(guān)閉 ===n");
? ??return0;
}

在C語(yǔ)言中,沒(méi)有類(lèi)的概念,因此我們通過(guò)靜態(tài)全局變量和函數(shù)來(lái)模擬單例模式。

私有靜態(tài)實(shí)例:靜態(tài)全局指針static StateManager* instance = NULL;,它指向唯一的實(shí)例。而實(shí)例本身是在獲取函數(shù)內(nèi)部使用靜態(tài)局部變量static StateManager manager;來(lái)創(chuàng)建的。這樣,實(shí)例在程序運(yùn)行期間只被初始化一次,并且通過(guò)指針?lè)祷亍?/p>

私有構(gòu)造函數(shù):在C中,通過(guò)靜態(tài)初始化或在獲取函數(shù)內(nèi)部初始化來(lái)實(shí)現(xiàn)。在get_state_manager()函數(shù)中,通過(guò)靜態(tài)局部變量來(lái)創(chuàng)建實(shí)例,并只做一次初始化

公共的靜態(tài)方法:get_state_manager()函數(shù),它返回單例實(shí)例的指針。同時(shí),我們還提供了其他操作狀態(tài)的函數(shù),如set_system_mode(),?get_system_mode()等,這些函數(shù)內(nèi)部都會(huì)調(diào)用get_state_manager()來(lái)獲取單例實(shí)例。

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; ?// 非靜態(tài)成員鎖,保護(hù)實(shí)例狀態(tài)
? ??
? ? StateManager() =?default; ?// 私有構(gòu)造函數(shù)

public:
? ??// 刪除拷貝構(gòu)造函數(shù)和賦值運(yùn)算符
? ? StateManager(const?StateManager&) =?delete;
? ??voidoperator=(const?StateManager&) =?delete;

? ??// 使用局部靜態(tài)變量實(shí)現(xiàn)線(xiàn)程安全的單例
? ??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";
? ? }
};

// 測(cè)試函數(shù)
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;
? ??
? ??// 創(chuàng)建多個(gè)線(xiàn)程測(cè)試線(xiàn)程安全
? ??for?(int?i =?1; i <=?5; ++i) {
? ? ? ? threads.emplace_back(threadTask, i);
? ? }
? ??
? ??// 等待所有線(xiàn)程完成
? ??for?(auto& t : threads) {
? ? ? ? t.join();
? ? }

? ??// 主線(xiàn)程訪問(wèn)
? ? StateManager::getInstance().printState();
? ??return0;
}

2、優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

(1)資源高效性

內(nèi)存節(jié)省

    • :僅一個(gè)實(shí)例,減少重復(fù)對(duì)象占用的RAM(關(guān)鍵于資源受限MCU)。

性能提升

    :避免頻繁創(chuàng)建/銷(xiāo)毀對(duì)象(如通信協(xié)議棧),降低CPU開(kāi)銷(xiāo)。

(2)行為一致性

    防止硬件狀態(tài)沖突(如多任務(wù)同時(shí)配置UART波特率)。確保全局?jǐn)?shù)據(jù)(如校準(zhǔn)參數(shù))唯一可信。
缺點(diǎn):

(1)擴(kuò)展性差:缺乏抽象層,難以通過(guò)繼承擴(kuò)展功能(違反開(kāi)閉原則)。

(2)生命周期問(wèn)題:靜態(tài)實(shí)例長(zhǎng)期占用內(nèi)存,若未被利用則浪費(fèi)資源。

三、嵌入式場(chǎng)景適用性總結(jié)

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶(hù)資源
  • 寫(xiě)文章/發(fā)需求
立即登錄

本公眾號(hào)專(zhuān)注于嵌入式技術(shù),包括但不限于C/C++、嵌入式、物聯(lián)網(wǎng)、Linux等編程學(xué)習(xí)筆記,同時(shí),公眾號(hào)內(nèi)包含大量的學(xué)習(xí)資源。歡迎關(guān)注,一同交流學(xué)習(xí),共同進(jìn)步!