Open In App

thread_local Storage in C++ 11

Last Updated : 15 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// C++ Program to implement 
// thread_local Storage
#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()
{
    // Create first thread
    thread t1(increment_counter);
    // Create second thread
    thread t2(increment_counter);
    // Wait for the first thread to finish
    t1.join();
    // Wait for the second thread to finish
    t2.join();
    return 0;
}


Output

Thread 140093779908160 counter = 1
Thread 140093788300864 counter = 1

Example 2:

C++




// C++ Program to demonstrate the use of thread-local
// storage.
#include <iostream>
#include <thread>
  
using namespace std;
  
class Singleton {
public:
    static Singleton& getInstance()
    {
        // Each thread will have its own instance of
        // Singleton
        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()
{
    // Create first thread
    thread t1(workerThread);
    // Create second thread
    thread t2(workerThread);
  
    // Wait for the first thread to finish
    t1.join();
    // Wait for the second thread to finish
    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




// C++ Program to implement
// Static Thread Local Storage
#include <iostream>
#include <thread>
  
using namespace std;
  
void thread_func()
{
    // Static thread-local variable
    static thread_local int stls_variable = 0;
    // Increment the variable
    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.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads