如何分配线程本地存储
How to allocate thread local storage?
我的函数中有一个静态变量,但我希望它在每个线程的基础上都是静态的。
如何为 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
是最好的方法,因为它是便携式解决方案。
在Linux和GCC上,你可以使用__thread
修饰符。
因此,您的实例变量将如下所示:
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();
}
如果您使用的是 MSVC++,则可以阅读线程本地存储 (TLS)
然后你可以看到这个例子。
另外,请注意 TLS 的规则和限制
C++11 指定了thread_local
存储类型,只需使用它即可。
AnotherClass::threadSpecificAction()
{
thread_local MyClass *instance = new MyClass();
instance->doSomething();
}
一个可选的优化是同时分配线程本地存储。
在Windows上,您可以使用TlsAlloc和TlsFree在线程本地存储中分配存储。
要使用 TLS 设置和检索值,您可以分别使用 TlsSetValue 和 TlsGetValue
。在这里,您可以看到有关如何使用它的示例。
只是一个旁注...MSVC++ 支持 VSC++2005 中的 declspec(thread)
#if (_MSC_VER >= 1400)
#ifndef thread_local
#define thread_local __declspec(thread)
#endif
#endif
主要问题是(在 boost::thread_specific_ptr 中解决了)标有它的变量不能包含 ctor 或 dtor。
Folly(Facebook开源库)具有Thread Local Storage的可移植实现。
根据其作者:
改进了非平凡类型的线程本地存储(速度与
pthread_getspecific
但只消耗一个pthread_key_t
,速度快 4 倍 比boost::thread_specific_ptr
)。
如果您正在寻找本地存储线程的可移植实现,此库是一个不错的选择。
- 将线程中的数据存储到全局容器的最佳方法?
- C++ 多线程原子加载/存储
- 混合 c++ 和 .net 的线程本地存储
- 存储/传递 v8 承诺解析器供以后使用的最佳实践?(结合C++线程)
- 线程上下文上的静态存储对象优化
- 在容器中存储指向对象的指针时的线程安全
- 多线程存储到文件中
- 如何使一个线程中的内存存储"promptly"在其他线程中可见?
- 创建一个以存储线程并调用它们的类
- Apache 崩溃并显示错误 R6016 没有足够的空间来存储线程数据
- Valgrind:在多线程程序中发现冲突的存储/加载
- C 静态与线程存储持续时间破坏顺序
- 线程特定数据与线程本地存储
- 多个动态链接库(DLL)是否可以从静态库(LIB)共享线程本地存储
- 线程本地存储(TLS)和OpenMP
- 线程本地存储构造函数 g++
- 在C++中将所有TLS(线程本地存储)变量设置为新的单个值
- 如何确保变量在不同的线程读取它们之前存储到内存中
- 是块作用域静态或线程存储持续时间变量初始化失败的原因
- 基于UNIX的聊天室::使用getch()、POSIX线程存储每个字符