Thread-local data is stored separately for each executing thread. Prefer passing thread-specific data through function arguments or keeping state in local variables; use thread-local storage when that is impractical. section 18.3
One declaration, one instance per thread
Declare a variable with the C storage-class specifier _Thread_local; the threads.h macro thread_local expands to the same keyword. Each thread then receives a separate instance. Such variables follow static-duration declaration rules: file-scope declarations are allowed, while block-scope declarations additionally require static. Because initialization cannot be dynamic, use thread_local when the initial value can be determined at compile time. section 18.3 section 13.2
When per-thread data needs dynamic construction or destruction, use C thread-specific storage instead. A tss_t key identifies the data opaquely; tss_set stores a pointer, tss_get retrieves it, and a destructor can run when the thread ends. section 18.3
void* tss_get(tss_t key); // Returns a pointer to an object
int tss_set(tss_t key, void *val); // Returns an error indication
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":4}],[{\"line\":1,\"ch\":23},{\"line\":1,\"ch\":27}],[{\"line\":0,\"ch\":6},{\"line\":0,\"ch\":13}],[{\"line\":0,\"ch\":14},{\"line\":0,\"ch\":19}],[{\"line\":1,\"ch\":12},{\"line\":1,\"ch\":17}],[{\"line\":0,\"ch\":51},{\"line\":0,\"ch\":54}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":3}],[{\"line\":1,\"ch\":4},{\"line\":1,\"ch\":11}],[{\"line\":0,\"ch\":14},{\"line\":0,\"ch\":19}],[{\"line\":1,\"ch\":12},{\"line\":1,\"ch\":17}],[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":4}],[{\"line\":1,\"ch\":23},{\"line\":1,\"ch\":27}]]"}
!@%STYLE%@!
Use the tss_get and tss_set declarations as the compact interface for retrieving and assigning per-thread objects. section 18.3
typedef void (*tss_dtor_t)(void*); // Pointer to a destructor
int tss_create(tss_t* key, tss_dtor_t dtor); // Returns an error indication
void tss_delete(tss_t key);
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":12}],[{\"line\":0,\"ch\":15},{\"line\":0,\"ch\":25}],[{\"line\":1,\"ch\":27},{\"line\":1,\"ch\":37}],[{\"line\":0,\"ch\":8},{\"line\":0,\"ch\":12}],[{\"line\":2,\"ch\":0},{\"line\":2,\"ch\":4}],[{\"line\":0,\"ch\":50},{\"line\":0,\"ch\":53}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":3}],[{\"line\":1,\"ch\":4},{\"line\":1,\"ch\":14}],[{\"line\":1,\"ch\":15},{\"line\":1,\"ch\":20}],[{\"line\":2,\"ch\":16},{\"line\":2,\"ch\":21}],[{\"line\":0,\"ch\":15},{\"line\":0,\"ch\":25}],[{\"line\":1,\"ch\":27},{\"line\":1,\"ch\":37}],[{\"line\":0,\"ch\":8},{\"line\":0,\"ch\":12}],[{\"line\":2,\"ch\":0},{\"line\":2,\"ch\":4}],[{\"line\":2,\"ch\":5},{\"line\":2,\"ch\":15}],[{\"line\":1,\"ch\":15},{\"line\":1,\"ch\":20}],[{\"line\":2,\"ch\":16},{\"line\":2,\"ch\":21}]]"}
!@%STYLE%@!
Use tss_create with a tss_dtor_t destructor and tss_delete to manage the key supporting dynamically created thread-specific data. section 18.3
