How to allocate thread local storage?

时光毁灭记忆、已成空白 提交于 2019-11-27 05:04:08

问题


I have a variable in my function that is static, but I would like it to be static on a per thread basis.

How can I allocate the memory for my C++ class such that each thread has its own copy of the class instance?

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

  instance->doSomething();
}

This is on Linux. I'm not using C++0x and this is gcc v3.4.6.


回答1:


#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();



回答2:


It is worth noting that C++11 introduces the thread_local keyword.

Here is an example from Storage duration specifiers:

#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;
}

Possible output:

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



回答3:


boost::thread_specific_ptr is the best way as it portable solution.

On Linux & GCC you may use __thread modifier.

So your instance variable will look like:

static __thread MyClass *instance = new MyClass();



回答4:


If you're using Pthreads you can do the following:

//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();
}



回答5:


C++11 specifies a thread_local storage type, just use it.

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

One optional optimization is to also allocate on thread local storage.




回答6:


If you're working with MSVC++, you can read Thread Local Storage (TLS)

And then you can see this example.

Also, be aware of the Rules and Limitations for TLS




回答7:


On Windows you can use TlsAlloc and TlsFree to allocate storage in the threads local storage.

To set and retrieve values in with TLS, you can use TlsSetValue and TlsGetValue, respectively

Here you can see an example on how it would be used.




回答8:


Just a side note... MSVC++ supports declspec(thread) from VSC++2005

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

Main problem is(which is solved in boost::thread_specific_ptr) variables marked with it can't contain ctor or dtor.




回答9:


Folly (Facebook Open-source Library) has a portable implementation of Thread Local Storage.

According its authors:

Improved thread local storage for non-trivial types (similar speed as pthread_getspecific but only consumes a single pthread_key_t, and 4x faster than boost::thread_specific_ptr).

If your looking for a portable implementation of Local Storage Thread, this library is a good option.



来源:https://stackoverflow.com/questions/6021273/how-to-allocate-thread-local-storage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!