What does the thread_local mean in C++11?

polapts picture polapts · Aug 16, 2012 · Viewed 80.2k times · Source

I am confused with the description of thread_local in C++11. My understanding is, each thread has unique copy of local variables in a function. The global/static variables can be accessed by all the threads (possibly synchronized access using locks). And the thread_local variables are visible to all the threads but can only modified by the thread for which they are defined? Is it correct?

Answer

paxdiablo picture paxdiablo · Aug 16, 2012

Thread-local storage duration is a term used to refer to data that is seemingly global or static storage duration (from the viewpoint of the functions using it) but in actual fact, there is one copy per thread.

It adds to the current automatic (exists during a block/function), static (exists for the program duration) and dynamic (exists on the heap between allocation and deallocation).

Something that is thread-local is brought into existence at thread creation and disposed of when the thread stops.

Some examples follow.

Think of a random number generator where the seed must be maintained on a per-thread basis. Using a thread-local seed means that each thread gets its own random number sequence, independent of other threads.

If your seed was a local variable within the random function, it would be initialised every time you called it, giving you the same number each time. If it was a global, threads would interfere with each other's sequences.

Another example is something like strtok where the tokenisation state is stored on a thread-specific basis. That way, a single thread can be sure that other threads won't screw up its tokenisation efforts, while still being able to maintain state over multiple calls to strtok - this basically renders strtok_r (the thread-safe version) redundant.

Both these examples allow for the thread local variable to exist within the function that uses it. In pre-threaded code, it would simply be a static storage duration variable within the function. For threads, that's modified to thread local storage duration.

Yet another example would be something like errno. You don't want separate threads modifying errno after one of your calls fails but before you can check the variable, and yet you only want one copy per thread.

This site has a reasonable description of the different storage duration specifiers.