thread_local Storage in C++ 11
Last Updated :
15 May, 2023
Thread local storage (TLS) is a feature introduced in C++ 11 that allows each thread in a multi-threaded program to have its own separate instance of a variable. In simple words, we can say that each thread can have its own independent instance of a variable. Each thread can access and modify its own copy of the variable without interfering with other threads.
Syntax
thread_local int my_variable;
Properties of Thread Local Storage (TLS)
- Lifetime: The lifetime of a TLS variable begins when it is initialized and ends when the thread terminates.
- Visibility: TLS variables have visibility at the thread level.
- Scope: TLS variables have scope depending on where they are declared
Examples of thread_local Storage
Example 1:
C++
#include <iostream>
#include <thread>
using namespace std;
thread_local int counter = 0;
void increment_counter()
{
counter++;
cout << "Thread " << this_thread::get_id()
<< " counter = " << counter << endl;
}
int main()
{
thread t1(increment_counter);
thread t2(increment_counter);
t1.join();
t2.join();
return 0;
}
|
Output
Thread 140093779908160 counter = 1
Thread 140093788300864 counter = 1
Example 2:
C++
#include <iostream>
#include <thread>
using namespace std;
class Singleton {
public :
static Singleton& getInstance()
{
thread_local Singleton instance;
return instance;
}
void printMessage()
{
cout << "Hello from thread "
<< this_thread::get_id() << endl;
}
private :
Singleton() = default ;
};
void workerThread()
{
Singleton::getInstance().printMessage();
}
int main()
{
thread t1(workerThread);
thread t2(workerThread);
t1.join();
t2.join();
return 0;
}
|
Output
Hello from thread 139683844367936
Hello from thread 139683852760640
Static Thread Local Storage
It allows each thread to have its own separate instance of a static variable. Similar to TLS, each thread can access and modify its own copy of the static variable without affecting other threads but with static storage duration, which means the variable persists across multiple invocations of the function within the same thread.
Example:
C++14
#include <iostream>
#include <thread>
using namespace std;
void thread_func()
{
static thread_local int stls_variable = 0;
stls_variable += 1;
cout << "Thread ID: " << this_thread::get_id()
<< ", Variable: " << stls_variable
<< endl;
}
int main()
{
thread t1(thread_func);
thread t2(thread_func);
t1.join();
t2.join();
return 0;
}
|
Output
Thread ID: 140702226085440, Variable: 1
Thread ID: 140702234478144, Variable: 1
Rules and limitations
- thread_local can not be used with function declarations or definitions. It can be used only for data declarations and definitions with static storage duration.
- If we declare any local variable with specifier thread_local, it is implicitly static. thread_local and static thread_local are equivalent if no other storage class is provided.
- We must use the thread_local specifier for both the declaration and the definition of a thread-local object. This applies to the case where the declaration and definition occur in the same file or separate files.
Conclusion
Thread local storage (TLS) in C++ allows each thread to have its own separate instance of a variable. TLS variables have their own lifetime, visibility, and scope within each thread. TLS can be used to maintain thread-specific data without interfering with other threads.
Share your thoughts in the comments
Please Login to comment...