Thread Local Data

  • C++ supports thread-local variables

    • Same as static and global variables
    • However, there is a separate object for each thread
    • With a static variable, there is a single object which is shared by all threads
  • We use the thread_local keyword to declare them

  • Global variables or at namespace scope

  • Data members of a class

  • Local variables in a function

Thread-local Variable Lifetimes

  • Global and namespace scope

    • Always constructed at or before the first use in a translation unit
    • It is safe to use them in dynamic libraries (DLLs)
  • Local variables

    • Initialized in the same way as static local variables
  • In all cases

    • Destroyed when the thread completes its execution

Thread-local variable Example

  • We can make a random number engine thread-local

    • This gives each thread its own object
  • This ensures that each thread generates the same sequence

    • Useful for testing

(without thread local, the output would not be the same).

#include <iostream>
#include <random>
#include <thread>

// Thread-local random number engine
thread_local std::mt19937 mt;

void func() {
  std::uniform_real_distribution<double> dist(0, 1);

  for (int i = 0; i < 10; ++i)
    std::cout << dist(mt) << " , ";
}

int main() {
  // These two threads generates the same output.
  std::cout << "Thread 1's random values: \n";
  std::thread thr1(func);
  thr1.join();

  std::cout << "\nThread 2's random values: \n";
  std::thread thr2(func);
  thr2.join();
  std::cout << '\n';
}