C ++ 11:不平凡线程局部静态变量? [英] C++11: Nontrivial Thread Local Static Variable?

查看:353
本文介绍了C ++ 11:不平凡线程局部静态变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类X:

  class X {...} 

我想这样做:

  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;
//添加线程清理,调用析构函数
}

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

int main()
{
f();
}

这修复了动态内存分配问题。我只需要添加线程清理处理程序。

解决方案

标准描述 thread_local 作为其他的存储说明符( static extern 等)。对该单词的任何定义没有对简单数据类型的限制。



问题在pre-C++11讨论文档N2147 (请参见线程变量动态初始化一节)。这包括对正确实现所涉及的关键问题的描述。显然,GCC实现( static __thread )还没有解决这些问题(这与GCC不正式支持C ++ 11 thread_local )。



一个替代方法是 boost :: thread_specfic_ptr<> 此较早的文章,并说明了此处



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


I have a class X:

class X { ... }

I want to do this:

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

    ...
}

(actually I'm using gcc so keyword is "__thread")

but I can't because you can only have trivial thread_locals.

What is the best work-around for this?

If I do it this way:

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

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

    X& x = *p;

    ...
}

then:

  1. the destructor won't be called when thread exits
  2. unnecessary dynamic memory allocation.

Update:

Here is what I have so far:

#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();
}

This fixes the dynamic memory allocation problem. I just need to add the thread cleanup handler. Is there a mechanism to do this with pthreads?

解决方案

The Standard describes thread_local as a storage specifier like the others (static, extern etc.) in §7.1.1. There is no restriction to "simple" data types by any definition of that word.

The problem is briefly discussed in a pre-C++11 discussion document N2147 (see the section "Thread Variable Dynamic Initialization"). That includes a description of the key problems involved in the proper implementation. Apparently the GCC implementation (static __thread) hasn't solved these problems yet (which is consistent with the fact that GCC does not officially support C++11 thread_local).

One alternative is boost::thread_specfic_ptr<> mentioned in this earlier post and described here.

Another alternative is to use a std::thread object to implement the thread and ensure each instance maintains its own copy of the variable, possibly wrapped in a unique_ptr.

这篇关于C ++ 11:不平凡线程局部静态变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆