I am currently trying to better understand thread local storage in C++. To this end I wrote the following example:
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <chrono>
thread_local int thread_index;
std::vector<int*> pointers;
std::mutex mutex;
void show_index()
{
{
thread_index = 0;
std::lock_guard<std::mutex> lk(mutex);
pointers.push_back(&thread_index);
}
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lk(mutex);
std::cout << "Index of thread "
<< std::this_thread::get_id()
<< " : "
<< thread_index
<< std::endl;
}
}
}
void change_index()
{
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(3));
{
std::lock_guard<std::mutex> lk(mutex);
std::cout << "Thread "
<< std::this_thread::get_id()
<< " is changing indices"
<< std::endl;
for(auto& pointer : pointers)
{
++(*pointer);
}
}
}
}
int main()
{
std::vector<std::thread> threads;
for(int i = 0; i < 3; ++i)
{
threads.push_back(std::thread(show_index));
}
threads.push_back(std::thread(change_index));
for(auto& thread : threads)
{
thread.join();
}
return 0;
}
As can be seen the address of a thread_local
variable is leaked into the program and the thread local variables are inadvertedly changed by another thread. All access to the global state is protected by a std::mutex
, so there should not be an races. Indeed, I see the following expected output:
Index of thread 140443980949056 : 0
Index of thread 140443887072832 : 0
Index of thread 140443989341760 : 0
Index of thread 140443980949056 : 0
Index of thread 140443887072832 : 0
Index of thread 140443989341760 : 0
Thread 140443972556352 is changing indices
Index of thread 140443980949056 : 1
Index of thread 140443989341760 : 1
Index of thread 140443887072832 : 1
...
My question is: What does the standard say about accessing thread local variables from another thread? Is a thread local variable merely a pointer to memory that is guaranteed to be unique for each thread, or does the standard mandate "thread local" access as well?
Source: Windows Questions C++