2012-08-22 83 views
9

可能重複:
C++11 thread_local in gcc - alternatives
Is there any way to fully emulate thread_local using GCC's __thread?如何在C++中初始化線程局部變量?

我想用C++ 11 thread_local創建和使用thread_local變量,但它尚未由海灣合作委員會的支持,我我正在使用gcc特定的__thread。我聲明的變量的方法是

myClass 
{ 
public: 

    static __thread int64_t m_minInt; 

}; 
__thread int64_t myClass::m_minInt = 100; 

當我編譯它,我得到這樣

error: ‘myClass::minInt’ is thread-local and so cannot be dynamically initialized 

錯誤如何正確地做到這一點?

PS:gcc版本:4.6.3

+6

@betabandido您鏈接的問題討論了在C++ 11中thread_local的替代方案。我的問題是如何使用gcc的__thread。特別是有問題的錯誤消息。我試圖在其他地方找到它,但無法得到它。謝謝。 – polapts

回答

5

您需要使用延遲初始化。

myClass 
{ 
public: 

    static __thread int64_t m_minInt; 
    static __thread bool m_minIntInitialized; 

    static int64_t getMinInt(); 
}; 
__thread int64_t myClass::m_minInt; 
__thread bool myClass::m_minIntInitialized; 


int64_t myClass::getMinInt() 
{ 
    if (!m_minIntInitialized) // note - this is (due to __thread) threadsafe 
    { 
    m_minIntInitialized = true; 
    m_minInt = 100; 
    } 

    return m_minInt; 
} 

m_minIntInitialized保證爲零。

在大多數情況下(ELF specification)它被放置在零初始化的.tbss節中。

對於C++ - http://en.cppreference.com/w/cpp/language/initialization

對於其他所有非本地靜態和線程局部變量,零 初始化發生。在實踐中,將要初始化爲零初始化的變量放置在程序 圖像的.bss段中,該程序段在磁盤上不佔用空間,並在加載程序時由操作系統 清零。

+7

你怎麼知道m_minIntInitialized最初是假的? – CygnusX1

+2

@ CygnusX1,我已經更新了答案。 – nothrow

+0

您有競爭條件:其他線程可以在標誌設置爲true後但在變量初始化之前讀取m_minInt; – gdy