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.
Thread Local Storage (TLS) is the method by which each thread in a given multithreaded process can allocate locations in which to store thread-specific data. Dynamically bound (run-time) thread-specific data is supported by way of the TLS API (TlsAlloc).
With thread local storage (TLS), you can provide unique data for each thread that the process can access using a global index. One thread allocates the index, which can be used by the other threads to retrieve the unique data associated with the index.
We need thread-local storage to create libraries that have thread-safe functions, because of the thread-local storage each call to a function has its copy of the same global data, so it's safe I like to point out that the implementation is the same for copy on write technique.
In some ways, TLS is similar to static data. The only difference is that TLS data are unique to each thread. Most thread libraries-including Windows and Pthreads-provide some form of support for thread-local storage; Java provides support as well.
#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();
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With