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

C++ 局部靜態變量多線程初始化不安全問題

     編輯:C++ 入門

現象

函數內 static T obj; 首次調用時初始化。多線程並發首次調用可能導致重複構造,造成資源洩漏或邏輯錯誤。

底層機制 (編譯器生成代碼)

class Base { 
public: 
    Base() { ptr = new int[100]; } 
    ~Base() { delete[] ptr; }
    int* ptr;
};

void foo() { static Base b; } // 多線程調用
// 可能構造兩次,第二次構造覆蓋 ptr,第一次內存洩漏
// 析構時雙重 delete → 崩潰

解決方案

C++11 及以上:魔法靜態 (線程安全)

標準保證 static 區域變量初始化線程安全 (雙重檢查鎖模式)。直接使用即可。

C++03 / 舊編譯器:手動同步

// 方案 1:全局/類靜態成員 + pthread_once / CallOnce
Base& getInstance() {
    static Base* instance = nullptr;
    static pthread_once_t once = PTHREAD_ONCE_INIT;
    pthread_once(&once, []{ instance = new Base(); });
    return *instance;
}

// 方案 2:互斥鎖雙重檢查 (需 volatile/atomic 修飾 guard)
Base& getInstance() {
    static Base* instance = nullptr;
    static mutex mtx;
    if (!instance) {
        lock_guard<mutex> lock(mtx);
        if (!instance) instance = new Base();
    }
    return *instance;
}

最佳實踐

  • 優先升級編譯器啟用 C++11 (-std=c++11 / /std:c++14)
  • 避免在高併發熱點路徑首次初始化靜態對象
  • 單例模式改用 std::call_once 或 C++11 魔法靜態
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved