如何分配线程本地存储?

我在我的函数中有一个variables是静态的,但我希望它在每个线程的基础上是静态的。

我怎样才能为我的C ++类分配内存,使得每个线程都有自己的类实例副本?

AnotherClass::threadSpecificAction() { // How to allocate this with thread local storage? static MyClass *instance = new MyClass(); instance->doSomething(); } 

这是在Linux上。 我没有使用C ++ 0x,这是gcc v3.4.6。

 #include <boost/thread/tss.hpp> static boost::thread_specific_ptr< MyClass> instance; if( ! instance.get() ) { // first time called by this thread // construct test element to be used in all subsequent calls from this thread instance.reset( new MyClass); } instance->doSomething(); 

值得注意的是C ++ 11引入了thread_local关键字。

以下是存储时间说明符的一个示例:

 #include <iostream> #include <string> #include <thread> #include <mutex> thread_local unsigned int rage = 1; std::mutex cout_mutex; void increase_rage(const std::string& thread_name) { ++rage; std::lock_guard<std::mutex> lock(cout_mutex); std::cout << "Rage counter for " << thread_name << ": " << rage << '\n'; } int main() { std::thread a(increase_rage, "a"), b(increase_rage, "b"); increase_rage("main"); a.join(); b.join(); return 0; } 

可能的输出:

 Rage counter for a: 2 Rage counter for main: 2 Rage counter for b: 2 

boost::thread_specific_ptr是便携式解决scheme的最佳方式。

在Linux和GCC上,你可以使用__thread修饰符 。

所以你的实例variables将如下所示:

 static __thread MyClass *instance = new MyClass(); 

如果您正在使用Pthreads,则可以执行以下操作:

 //declare static data members pthread_key_t AnotherClass::key_value; pthread_once_t AnotherClass::key_init_once = PTHREAD_ONCE_INIT; //declare static function void AnotherClass::init_key() { //while you can pass a NULL as the second argument, you //should pass some valid destrutor function that can properly //delete a pointer for your MyClass pthread_key_create(&key_value, NULL); } void AnotherClass::threadSpecificAction() { //Initialize the key value pthread_once(&key_init_once, init_key); //this is where the thread-specific pointer is obtained //if storage has already been allocated, it won't return NULL MyClass *instance = NULL; if ((instance = (MyClass*)pthread_getspecific(key_value)) == NULL) { instance = new MyClass; pthread_setspecific(key_value, (void*)instance); } instance->doSomething(); } 

C ++ 11指定了一个thread_local存储types,只是使用它。

 AnotherClass::threadSpecificAction() { thread_local MyClass *instance = new MyClass(); instance->doSomething(); } 

一个可选的优化也是在线程本地存储上分配。

如果您正在使用MSVC ++,则可以阅读线程本地存储(TLS)

然后你可以看到这个例子 。

此外,请注意TLS的规则和限制

在Windows上,您可以使用TlsAlloc和TlsFree在线程本地存储中分配存储空间。

要使用TLS设置和检索值,可以分别使用TlsSetValue和TlsGetValue

在这里你可以看到一个关于如何使用的例子。

只是一个侧面说明… MSVC ++支持从VSC ++ 2005 declspec(线程)

 #if (_MSC_VER >= 1400) #ifndef thread_local #define thread_local __declspec(thread) #endif #endif 

主要的问题是(这是解决在boost :: thread_specific_ptr)标有它的variables不能包含ctor或dtor。

愚蠢的(Facebook的开源库)有一个线程本地存储的便携式实现。

根据其作者:

改进了非平凡types的线程本地存储(类似于pthread_getspecific速度,但只消耗一个pthread_key_t ,比boost::thread_specific_ptr快4倍)。

如果你正在寻找一个本地存储线程的可移植实现,这个库是一个不错的select。