C ++ 11:不平凡线程局部静态变量? [英] C++11: Nontrivial Thread Local Static Variable?
问题描述
我有一个类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;
...
}
>
- 当线程退出时,析构函数不会被调用
- 不必要的动态内存分配。
更新:
#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:
- the destructor won't be called when thread exits
- 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屋!