線程局部存儲(chǔ)

線程局部存儲(chǔ)

線程局部存儲(chǔ)(TLS,thread local storage) 就是擁有線程生命周期及線程可見(jiàn)性的變量。

線程局部存儲(chǔ)實(shí)際上是由單線程程序中的全局/靜態(tài)變量被應(yīng)用到多線程程序中被線程共享而來(lái)。我們可以簡(jiǎn)單地回顧一下所謂的線程模型。通常情況下,線程會(huì)擁有自己的棧空間,但是堆空間、靜態(tài)數(shù)據(jù)區(qū)則是共享的。這樣一來(lái),全局、靜態(tài)變量在這種多線程模型下總是再線程間共享的。

全局,靜態(tài)變量的共享會(huì)帶來(lái)好處,但是并不是所有的全局,靜態(tài)變量適合在在多線程的情況下共享。

#include <pthread.h>
#include <iostream>

int errorCode = 0;

void* MaySetErr(void* input)
{
    if (*(int *)input == 1)
        errorCode = 1;
    else if (*(int *)input == 2)
        errorCode = -1;
    else
        errorCode = 0;
}

int main()
{
    int input_a = 1;
    int input_b = 2;

    pthread_t thread1, thread2;

    pthread_create(&thread1, NULL, &MaySetErr, &input_a);
    pthread_create(&thread2, NULL, &MaySetErr, &input_b);

    pthread_join(thread2, NULL);
    pthread_join(thread1, NULL);

    std::cout << errorCode << std::endl;

    return 0;
}

errorCode 值無(wú)法確定。因?yàn)?線程1 和 線程2 的執(zhí)行順序是無(wú)法確定的。
實(shí)際上,本例中 errorCode 即是 POSIX 標(biāo)準(zhǔn)中的錯(cuò)誤全局變量 errno 在多線程情況下遇到問(wèn)題的一個(gè)簡(jiǎn)化。
一旦 errno 在線程間共享時(shí),則一些程序中允許的錯(cuò)誤將會(huì)被隱藏不報(bào)。而解決方法就是為每個(gè)線程指派一個(gè)全局的 errno,即 TLS 化 的 errno。

不同的編譯器有不同的 TLS 標(biāo)準(zhǔn)。

g++/clang++/xlc++ 可以看到如下語(yǔ)法:

__thread int errCode;

每個(gè)線程擁有獨(dú)立的 errCode 的拷貝,一個(gè)線程中的 errCode 的讀寫并不會(huì)影響另一個(gè)線程中的 errCode。

C++11 對(duì) TLS 標(biāo)準(zhǔn)做了統(tǒng)一的規(guī)定。

int thread_local errCode;

對(duì) thread_local 變量地址取值(&),也只能獲得當(dāng)前現(xiàn)場(chǎng)中 TLS 變量的地址值。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容