2012-08-22 48 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