Program:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
std::mutex mutexCout;
thread_local string
welcomeMessage = "Executing ";
void checkThreadLocal(string
const& threadName)
{
welcomeMessage.append(threadName);
lock_guard<mutex> guard(mutexCout);
cout << welcomeMessage << endl;
}
int main()
{
thread t1(checkThreadLocal, "thread1 ");
thread t2(checkThreadLocal, "thread2 ");
thread t3(checkThreadLocal, "thread3 ");
thread t4(checkThreadLocal, "thread4 ");
t1.join();
t2.join();
t3.join();
t4.join();
}
Output:
Executing thread1
Executing thread2
Executing thread3
Executing thread4
Output of program shows that local string is created for each string welcomeMessage
- Thread-specific data: Sometimes, you need data that is specific to each thread. For example, you might want to maintain a thread-local cache or store thread-specific configuration settings. thread_local allows you to declare variables that are unique to each thread, making it convenient to work with thread-specific data.
- Thread safety: In multi-threaded programs, global variables are shared among threads and can lead to race conditions if not properly synchronized. By using thread_local, you can avoid race conditions by ensuring that each thread has its own copy of the variable. This can simplify thread synchronization and improve thread safety.
- Performance optimization: In some cases, using thread-local variables can improve performance by reducing contention for shared resources. For example, if multiple threads frequently access a global variable, using thread_local to declare a separate copy of the variable for each thread can reduce cache invalidation and contention, leading to better performance.
- Avoiding mutex overhead: In scenarios where thread-local variables can replace the need for mutexes or other synchronization mechanisms, using thread_local can help avoid the overhead associated with locking and unlocking mutexes, leading to better performance.