The __thread storage class specifier
The __thread storage class marks a static variable as having thread-local storage duration. This means that, in a multithreaded application, a unique instance of the variable is created for each thread that uses it, and destroyed when the thread terminates. The __thread storage class specifier can provide a convenient way of assuring thread-safety: declaring an object as per-thread allows multiple threads to access the object without the concern of race conditions, while avoiding the need for low-level programming of thread synchronization or significant program restructuring.
__thread int i __attribute__((tls_model("local-exec")));
The tls_model attribute allows the linker to check that the correct thread model has been used to build the application or shared library. The linker/loader behavior is as follows:
Access method | Link-time diagnostic | Runtime diagnostic |
---|---|---|
local-exec | Fails if referenced symbol is imported. | Fails if module is not the main program. Fails if referenced symbol is imported (but the linker should have detected the error already). |
initial-exec | None. | dlopen() fails if referenced symbol is not in the module loaded at execution time. |
local-dynamic | Fails if referenced symbol is imported. | Fails if referenced symbol is imported (but the linker should have detected the error already). |
global-dynamic | None. | None. |
The specifier can be applied to variables with static storage duration. It cannot be applied to function-scoped or block-scoped automatic variables or non-static data members.
__thread int i;
extern __thread struct state s;
static __thread char *p;
A thread variable must
be initialized with a constant expression.
Applying address operator (&) to a thread-local variable returns the runtime address of the current thread's instance of the variable. That thread can pass this address to any other thread; however, when the first thread terminates, any pointers to its thread-local variables become invalid.