C++ 如何分配线程本地存储?
我的函数中有一个静态变量,但我希望它在每个线程的基础上是静态的 <>我如何分配内存给我的C++类,这样每个线程都有自己的类实例的拷贝?C++ 如何分配线程本地存储?,c++,linux,multithreading,new-operator,thread-local-storage,C++,Linux,Multithreading,New Operator,Thread Local Storage,我的函数中有一个静态变量,但我希望它在每个线程的基础上是静态的 我如何分配内存给我的C++类,这样每个线程都有自己的类实例的拷贝? AnotherClass::threadSpecificAction() { // How to allocate this with thread local storage? static MyClass *instance = new MyClass(); instance->doSomething(); } 这是在Linux上实现的。我
AnotherClass::threadSpecificAction()
{
// How to allocate this with thread local storage?
static MyClass *instance = new MyClass();
instance->doSomething();
}
这是在Linux上实现的。我没有使用C++0x,这是gcc v3.4.6。如果您使用的是MSVC++,您可以阅读 然后你可以看到这个 另外,请注意Windows上的,您可以在线程本地存储中使用和分配存储 要使用TLS设置和检索中的值,可以分别使用和 您可以看到如何使用它的示例。
\include
#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();
静态boost::特定于线程的ptr实例;
如果(!instance.get()){
//此线程第一次调用
//构造要在此线程的所有后续调用中使用的测试元素
重置(新的MyClass);
}
实例->doSomething();
如果使用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();
}
是最好的方式,因为它是便携式解决方案
在Linux和GCC上,您可以使用
因此,您的实例变量如下所示:
static __thread MyClass *instance = new MyClass();
值得注意的是,C++11引入了
thread\u local
关键字
以下是一个例子:
只是一个旁注。。。
MSVC++支持VSC++2005中的declspec(线程)
#if (_MSC_VER >= 1400)
#ifndef thread_local
#define thread_local __declspec(thread)
#endif
#endif
主要问题是(在boost::thread_-specific_-ptr中解决了)标记为ctor或dtor的变量不能包含ctor或dtor。C++11指定了一种存储类型,只需使用它即可
AnotherClass::threadSpecificAction()
{
thread_local MyClass *instance = new MyClass();
instance->doSomething();
}
一个可选的优化是也分配线程本地存储。具有线程本地存储的可移植实现
其作者认为:
改进了非平凡类型的线程本地存储(与
pthread\u getspecific
但只使用一个pthread\u key\t
,速度快4倍
而不是boost::thread\u specific\u ptr
)
如果您正在寻找本地存储线程的可移植实现,则此库是一个不错的选择。取决于您是在Windows上还是在其他地方。取决于。如果您使用boost:您需要提供关于实际平台的更多信息,包括您是否可以/想要使用C++0x功能(在您的平台中可能可用,也可能不可用,因此,平台很重要:操作系统、编译器和版本)。不要为特定于操作系统的东西而烦恼,
boost::thread\u specific\u ptr
是干净的、可移植的和惯用的。@entheh:所谓超级懒惰,你指的是那些重视构造良好的示例代码的人?=)。请注意,如果Excel线程是Booost的,则只执行*实例:线程的原始问题是关于“静态”线程局部的,这正是通过螺纹特定ptr
代码更复杂,不符合标准。虽然在这里不是正确的选择,thread\u specific\u ptr
对于动态分配线程本地对象仍然很有用。@user2913094 GCC 3.4不奇怪没有这个功能。另外,GCC4.6和MSVC GCC在4.8中增加了对thread\u local
的支持。如果您使用的是4.7或更早版本,则需要使用\u thread
来指定存储类。这正是我需要的。但是为什么需要互斥呢?科学对于每个线程,thead\u local
都是私有的?@reavenisadesk,对于任何thread\u local
变量,都不需要mutex
。不幸的是,让thread\u local在OSX上工作有点像噩梦:@reavenisadesk,mutex
只是同步输出,因为流不会一次写入所有内容。如果没有锁,您可能会读到类似“Rage counter for Rage counter for aRage counter for:main”的内容……当心在使用_线程时没有在MyClass上执行析构函数。(boost::thread_specific_ptr或thread_local MyClass执行析构函数。)被否决,因为根据规则和限制,我看不出这是如何回答这个问题的。没有提到or.Upvoting,因为这个问题的标题没有提到Linux。搜索流量是由标题驱动的,而不是问题主体中的一些微妙的免责声明。但是,这些都是有用的链接。但在OS X或iOS上没有实现。@jupp0r那么您的OS X编译器不符合C++11:存储类说明符:static、thread_local、extern、mutable。@rustyx:是的,AppleClang不符合C++11(到目前为止,XCode8支持thread_local
)。这个问题在C++11中得到了解决,MSVC 2015(可能在2013年)也支持它。不过,没有windows支持(对于便携设备来说就这么多了)。
#if (_MSC_VER >= 1400)
#ifndef thread_local
#define thread_local __declspec(thread)
#endif
#endif
AnotherClass::threadSpecificAction()
{
thread_local MyClass *instance = new MyClass();
instance->doSomething();
}