C++11 thread_local關鍵字

牛犁heart發表於2023-03-07

這是一篇科普文--關於thread_local關鍵字

首先,C++11之前並沒有對併發進行任何的支援,C++11首次提供了以下的支援:

  • 語言核心定義了一個記憶體模型,保證當更改"被兩個不同執行緒使用"的兩個object時,他們彼此獨立,而引用thread_local關鍵字
  • 標準庫支援啟動多執行緒,包括傳遞引數、返回數值、跨執行緒邊界傳遞異常、同步化等,使得控制流程和資料訪問同步成為可能。

本節僅對thread_local進行學習


------不華麗的分割線------


拋個磚

如果一個執行緒掛起或兩個執行緒試圖同時訪問同一項資料,結果將如何?

引個玉

為了解決並行性問題,C++定義了一個支援執行緒化執行的記憶體模型,新增了關鍵字thread_local,提供了相關的庫支援。
關鍵字thread_local將變數宣告為靜態儲存,其持續性與特定執行緒相關:即定義這種變數的執行緒過期時,變數也將過期。

使用舉例:
例子來源C++11&14 Thread_local
C++11中就提出了thread_local這個變數修飾,用於解決執行緒沒有自己全域性變數的問題

#include <iostream>
#include <thread>

thread_local int i = 0;

int func(int val)
{
        i = val;
        i = i + 2;
        std::cout<<i;
}

int func2()
{
        std::cout<<i;
}

int main()
{
        i = 9;
        std::thread t1(func, 1);
        std::thread t2(func, 2);
        std::thread t3(func, 3);
        std::thread t4(func2);

        t1.join();
        t2.join();
        t3.join();
        t4.join();

        std::cout<<i<<std::endl;
        return 0;
}

執行結果:
image

使用thread_local修飾符在全域性宣告瞭一個i變數,i變數將被每個新建執行緒複製作為其域內全域性變數
執行緒1中的i變數和main中的i變數指向不同的地址
thread_local修飾後仍然是一個變數,依舊能夠使用取地址操作或透過引用的方法傳遞給其他執行緒