首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 線程安全單例工廠實現:雙重檢查鎖定模式

     編輯:關於C++

背景問題

常見的單例模式使用 static 局部變量(Meyers Singleton),但 C++11 前編譯器不保證其線程安全。即使 C++11 標準化了魔法靜態的線程安全初始化,某些舊編譯器/嵌入式平台可能不支持。本文實現一個顯式線程安全的單例工廠。

設計要點

  • 使用 Windows Critical Section(臨界區)實現互斥,輕量級、進程內同步
  • 雙重檢查鎖定:第一次無鎖檢查,為空才進入鎖區,再次檢查後創建
  • 模板類支持任意類型 T
  • std::auto_ptr 管理單例對象生命週期(C++11 前智能指針),析構時自動釋放
  • 工廠本身也是單例(CreateSingletonFactory 返回靜態實例)

完整代碼


#ifndef SINGLETONFACTORY_H
#define SINGLETONFACTORY_H

#include <windows.h>
#include <memory>

namespace Tools {

template<class T>
class SingletonFactory {
public:
    virtual ~SingletonFactory() {
        ::DeleteCriticalSection(&__criticalSection);
    }

    std::auto_ptr<T>& GetInstance();
    static SingletonFactory<T>* CreateSingletonFactory();

private:
    SingletonFactory() {
        ::InitializeCriticalSection(&__criticalSection);
    }

    std::auto_ptr<T> __singletonObj;
    CRITICAL_SECTION __criticalSection;
};

// 工廠單例創建(靜態局部變量,C++11 保證線程安全)
template<class T>
SingletonFactory<T>* SingletonFactory<T>::CreateSingletonFactory() {
    static SingletonFactory<T> temObj;
    return &temObj;
}

// 雙重檢查鎖定獲取單例實例
template<class T>
std::auto_ptr<T>& SingletonFactory<T>::GetInstance() {
    if (__singletonObj.get() == 0) {
        ::EnterCriticalSection(&__criticalSection);
        if (__singletonObj.get() == 0)
            __singletonObj = std::auto_ptr<T>(new T);
        ::LeaveCriticalSection(&__criticalSection);
    }
    return __singletonObj;
}

} // namespace Tools
#endif // SINGLETONFACTORY_H

測試代碼


struct Data1 { int x, y; };
struct Data2 { int x, y; };

int main() {
    // 獲取工廠單例,再獲取數據單例
    SingletonFactory<Data1>* factory1 = SingletonFactory<Data1>::CreateSingletonFactory();
    factory1->GetInstance()->x = 100;
    cout << factory1->GetInstance()->x << endl; // 100
    factory1->GetInstance()->y = 200;
    cout << factory1->GetInstance()->x << endl; // 100
    cout << factory1->GetInstance()->y << endl; // 200

    SingletonFactory<Data2>* factory2 = SingletonFactory<Data2>::CreateSingletonFactory();
    factory2->GetInstance()->x = 100;
    cout << factory2->GetInstance()->x << endl;
    factory2->GetInstance()->y = 200;
    cout << factory2->GetInstance()->x << endl;
    cout << factory2->GetInstance()->y << endl;
    return 0;
}

現代 C++ 改進建議

  • C++11 及以上:直接使用 static T instance 魔法靜態,標準保證線程安全,代碼極簡
  • 替換 std::auto_ptr 為 std::unique_ptr(C++11)或 std::shared_ptr
  • 跨平台:用 std::mutex + std::call_once 替代 Critical Section
  • 無鎖模式:std::atomic<T*> + 雙重檢查 + memory_order_acquire/release
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved