Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

pthread_key_create / pthread_getspecific (TSD family) - glibc

Split from the chapter glibc: Process, Threads and Signals into the per-function layout; see the method page and the glibc ledger for coverage status.

FieldValue
IDGLIBC-pthread_key_create, GLIBC-pthread_key_delete, GLIBC-pthread_getspecific, GLIBC-pthread_setspecific
Headerpthread.h
ProvenancePOSIX.1-1996; symbol versions GLIBC_2.34 (compat GLIBC_2.2.5)
WrapsTLS machinery (thread pointer + DTV), no syscall on get/set
Statusdocumented

Semantics – dynamic thread-specific data: pthread_key_create(key, destructor) allocates a process-wide key visible to all threads; each thread binds its own void * via pthread_setspecific and reads it with pthread_getspecific (initially NULL). At thread exit, destructors run in an unspecified order – cancellation step 2 in pthread_cancel(3)’s sequence – each on that thread’s value.

Destructor rules – pthread_key_delete does not run the destructor (for the calling thread or anyone) and does not free bound values; the C++11 thread_local objects are destroyed before TSD destructors, so a destructor must not touch thread_local state or use such objects as its argument. The ISO C twin (tss_create etc.) bounds destructor re-runs with TSS_DTOR_ITERATIONS – relevant when a destructor itself creates TSD.

glibc layer – glibc implements this over ELF TLS: the key table hangs off the thread pointer, so getspecific is a couple of loads with no syscall; a signal handler interrupting pthread_setspecific mid-allocation is the documented AC-unsafe window. errno itself is the canonical TSD user in a threaded program.

Example

static pthread_key_t log_key;
pthread_key_create(&log_key, free);
pthread_setspecific(log_key, strdup(name));
char *name = pthread_getspecific(log_key);

References – glibc manual Thread-specific Data; pthread_key_create(3) semantics via pthreads(7).