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上实现的。我

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

<>我如何分配内存给我的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。

如果您使用的是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的,则只执行*实例:线程的原始问题是关于“静态”线程局部的,这正是通过 THeLeLead本地/<代码>关键字构建的C++中的,因此他应该使用C++的本地支持,简单地说为<代码> thRead局部MyC类实例;代码>。本答案中的
螺纹特定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();
}