Variables are declared thread-local using the __thread keyword, as in the following examples.
__thread int i; __thread char *p; __thread struct state s;
During loop optimizations, the compiler can choose to create thread-local temporaries as needed.
The __thread keyword can be applied to any global, file-scoped static, or function-scoped static variable. It has no effect on automatic variables, which are always thread-local.
In C++, a thread-local variable can not be initialized if the initialization requires a static constructor. Otherwise, a thread-local variable can be initialized to any value that would be legal for an ordinary static variable.
No variable, thread-local or otherwise, can be statically initialized to the address of a thread-local variable.
Thread-local variables can be declared externally and referenced externally. Thread-local variables are subject to the same interposition rules as normal symbols.
Various TLS access models are available. See Thread-Local Storage Access Models. Shared object developers should be aware of the restrictions imposed by some of these access models in relation to object loading. A shared object can be dynamically loaded during process startup, or after process startup by means of lazy loading, filters, or dlopen(3C). At the completion of process startup, the thread pointer for the main thread is established. All static TLS storage requirements are calculated before the thread pointer is established.
Shared objects that reference thread-local variables, should insure that every translation unit containing the reference is compiled with a dynamic TLS model. This model of access provides the greatest flexibility for loading shared objects. However, static TLS models can generate faster code. Shared objects that use a static TLS model can be loaded as part of process initialization. However, after process initialization, shared objects that use a static TLS model can only be loaded if sufficient backup TLS storage is available. See Program Startup.
The address-of operator, &, can be applied to a thread-local variable. This operator is evaluated at runtime, and returns the address of the variable within the current thread. The address obtained by this operator can be used freely by any thread in the process as long as the thread that evaluated the address remains in existence. When a thread terminates, any pointers to thread-local variables in that thread become invalid.
When dlsym(3C) is used to obtain the address of a thread-local variable, the address that is returned is the address of the instance of that variable in the thread that called dlsym().