C ++ 11:非平凡线程局部静态变量?(C++11: Nontrivial Thread Loca

2019-07-31 03:02发布

我有一个X类:

class X { ... }

我想做这个:

void f()
{
    thread_local static X x = ...;

    ...
}

(其实我用gcc所以关键词是“__thread”)

但我不能,因为你只能有平凡thread_locals。

什么是最好的工作围绕这个?

如果我这样做,是这样的:

void f()
{
    thread_local static X* p = 0;

    if (!p)
       p = new X(...);

    X& x = *p;

    ...
}

然后:

  1. 析构函数将不会被调用线程退出时
  2. 不必要动态存储器分配。

更新:

这是我到目前为止有:

#include <iostream>
#include <type_traits>

using namespace std;

class X { public: X() { cout << "X::X()" << endl; }; ~X() { cout << "X::~X()" << endl; } };

void f()
{
        static __thread bool x_allocated = false;
        static __thread aligned_storage<sizeof(X),
             alignment_of<X>::value>::type x_storage;

        if (!x_allocated)
        {
                new (&x_storage) X;
                x_allocated = true;
                // add thread cleanup that calls destructor
        }

        X& x = *((X*) &x_storage);
}

int main()
{
        f();
}

这修正了动态内存分配的问题。 我只需要添加线程清理处理程序。 有没有一种机制并行线程来做到这一点?

Answer 1:

该标准描述thread_local为他人(等的存储说明符staticextern在§7.1.1等)。 没有限制的“简单”的数据类型由这个词的任何定义。

问题是在一个简要讨论预C ++ 11讨论文件N2147 (参见“线程变量的动态初始化”)。 这包括所涉及的正确实施的关键问题的说明。 显然,GCC实现( static __thread )没有解决这些问题,但(这是一个事实,即GCC不正式支持C ++ 11一致thread_local )。

一种选择是boost::thread_specfic_ptr<>中提到在这个早期的岗位和描述在这里 。

另一种方法是使用std::thread对象来实现线程,并确保每个实例维护自己的变量副本,可能裹着unique_ptr



Answer 2:

thread_local__thread是,其实不是一回事。 它们之间的主要区别是正是你偶然发现了一个- thread_local允许变量是非POD。 不幸的是,这也会影响性能。 见这个问题对于那些性能问题的更多细节。



文章来源: C++11: Nontrivial Thread Local Static Variable?