Linux's thread local storage implementation
It's a little complicated (this document explains it in great detail), but it's basically neither. Instead the compiler puts a special .tdata section in the executable, which contains all the thread-local variables. At runtime, a new data section for each thread is created with a copy of the data in the (read-only) .tdata section, and when threads are switched at runtime, the section is also switched automatically.
The end result is that __thread variables are just as fast as regular variables, and they don't take up extra stack space, either.
Implementation of Thread-local storage (TLS) in C/C++ (multithreading)
TLS is implemented as a data array within each thread object. Each thread object has its own local copy of the array, and each array is the same size. When you declare a global/static variable as using TLS, it is associated with an index into those arrays (that is how the compiler/OS knows how many array slots to allocate). Thus, when you access the variable at runtime, you are really accessing the associated slot in the data array of the thread context that is accessing the variable.
TLS may be a new native feature in C++11, but it has been available in various OS APIs for a long time.
TLS is implemented on Windows using the Win32 API TlsAlloc()
, TlsGetValue()
, TlsSetValue()
, and TlsFree()
functions. Here is an overview of how it works: Thread Local Storage
Here is an overview of how TLS works on Linux: ELF Handling For Thread-Local Storage
Thread Specific Data vs Thread Local Storage
The pthread_key_create
and friends are much older, and thus supported on more systems.
The __thread
is a relative newcomer, is generally much more convenient to use, and (according to Wikipedia) is supported on most POSIX systems that still matter: Solaris Studio C/C++, IBM XL C/C++, GNU C, Clang and Intel C++ Compiler (Linux systems).
The __thread
also has a significant advantage that it is usable from signal handlers (with the exception of using __thread
from dlopen
ed shared library, see this bug), because its use does not involve malloc
(with the same exception).
Related Topics
How to Record What Process or Kernel Activity Is Using the Disk in Gnu/Linux
Getting List of Network Devices Inside the Linux Kernel
Sending Keyboard Input to a Program from Command-Line
Help with Understanding a Very Basic Main() Disassembly in Gdb
Bash Alias with Argument and Autocompletion
How to Add Date String to Each Line of a Continuously Written Log File
Upstart Calling Script (For Inserted Usb-Drive)
Difference Between Flat Memory Model and Protected Memory Model
Windows Authentication Headers Without .Net. Possible
Extract Tar the Tar.Bz2 File Error
How to Reinstall the Latest Cmake Version
Error: Service "Xxx" Uses an Undefined Network "Xxx"
Using Linux How to Pass the Contents of a File as a Parameter to an Executable
How to Install Packages from Command Line on Suse
How to Cut First Column (Variable Length) of a String in Shell
Call to Daemon in a /Etc/Init.D Script Is Blocking, Not Running in Background