diff options
Diffstat (limited to 'man3/pthread_key_create.3')
-rw-r--r-- | man3/pthread_key_create.3 | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/man3/pthread_key_create.3 b/man3/pthread_key_create.3 new file mode 100644 index 0000000..1e7d680 --- /dev/null +++ b/man3/pthread_key_create.3 @@ -0,0 +1,178 @@ +.\" Copyright, Xavier Leroy <Xavier.Leroy@inria.fr> +.\" Copyright 2023, Alejandro Colomar <alx@kernel.org> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.TH pthread_key_create 3 2024-02-26 "Linux man-pages 6.7" +. +. +.SH NAME +pthread_key_create, +pthread_key_delete, +pthread_setspecific, +pthread_getspecific +\- +management of thread-specific data +. +. +.SH SYNOPSIS +.B #include <pthread.h> +.P +.BI "int pthread_key_create(pthread_key_t *" key ", void (*" destr_function ") (void *));" +.BI "int pthread_key_delete(pthread_key_t " key ");" +.BI "int pthread_setspecific(pthread_key_t " key ", const void *" pointer ");" +.BI "void * pthread_getspecific(pthread_key_t " key ");" +. +. +.SH DESCRIPTION +Programs often need global or static variables +that have different values in different threads. +Since threads share one memory space, +this cannot be achieved with regular variables. +Thread-specific data is the POSIX threads answer to this need. +.P +Each thread possesses a private memory block, +the thread-specific data area, +or TSD area for short. +This area is indexed by TSD keys. +The TSD area associates values of type \fBvoid *\fP to TSD keys. +TSD keys are common to all threads, +but the value associated with a given TSD key +can be different in each thread. +.P +For concreteness, +the TSD areas can be viewed as arrays of \fBvoid *\fP pointers, +TSD keys as integer indices into these arrays, +and the value of a TSD key +as the value of the corresponding array element in the calling thread. +.P +When a thread is created, +its TSD area initially associates \fBNULL\fP with all keys. +.P +\fBpthread_key_create\fP allocates a new TSD key. +The key is stored in the location pointed to by \fIkey\fP. +There is a limit of \fBPTHREAD_KEYS_MAX\fP +on the number of keys allocated at a given time. +The value initially associated with the returned key +is \fBNULL\fP in all currently executing threads. +.P +The \fIdestr_function\fP argument, +if not \fBNULL\fP, +specifies a destructor function associated with the key. +When a thread terminates via \fBpthread_exit\fP or by cancelation, +\fIdestr_function\fP is called with arguments +the value associated with the key in that thread. +The \fIdestr_function\fP is not called if that value is \fBNULL\fP. +The order in which destructor functions are called at thread termination time +is unspecified. +.P +Before the destructor function is called, +the \fBNULL\fP value is associated with the key in the current thread. +A destructor function might, +however, +re-associate non-\fBNULL\fP values to that key or some other key. +To deal with this, +if after all the destructors have been called +for all non-\fBNULL\fP values, +there are still some non-\fBNULL\fP values with associated destructors, +then the process is repeated. +The glibc implementation stops the process +after \fBPTHREAD_DESTRUCTOR_ITERATIONS\fP iterations, +even if some non-\fBNULL\fP values with associated descriptors remain. +Other implementations may loop indefinitely. +.P +\fBpthread_key_delete\fP deallocates a TSD key. +It does not check +whether non-\fBNULL\fP values are associated with that key +in the currently executing threads, +nor call the destructor function associated with the key. +.P +\fBpthread_setspecific\fP changes the value +associated with \fIkey\fP in the calling thread, +storing the given \fIpointer\fP instead. +.P +\fBpthread_getspecific\fP returns the value +currently associated with \fIkey\fP in the calling thread. +. +. +.SH "RETURN VALUE" +\fBpthread_key_create\fP, +\fBpthread_key_delete\fP, +and \fBpthread_setspecific\fP +return 0 on success and a non-zero error code on failure. +If successful, +\fBpthread_key_create\fP stores the newly allocated key +in the location pointed to by its \fIkey\fP argument. +.P +\fBpthread_getspecific\fP returns +the value associated with \fIkey\fP on success, +and \fBNULL\fP on error. +. +. +.SH ERRORS +\fBpthread_key_create\fP returns the following error code on error: +.RS +.TP +\fBEAGAIN\fP +\fBPTHREAD_KEYS_MAX\fP keys are already allocated. +.RE +.P +\fBpthread_key_delete\fP and \fBpthread_setspecific\fP return +the following error code on error: +.RS +.TP +\fBEINVAL\fP +\fIkey\fP is not a valid, allocated TSD key. +.RE +.P +\fBpthread_getspecific\fP returns \fBNULL\fP if \fIkey\fP is not a valid, +allocated TSD key. +. +. +.SH "SEE ALSO" +pthread_create(3), pthread_exit(3), pthread_testcancel(3). +. +. +.SH EXAMPLE +The following code fragment +allocates a thread-specific array of 100 characters, +with automatic reclamation at thread exit: +.P +.RS +.ft 3 +.nf +.sp +/* Key for the thread-specific buffer */ +static pthread_key_t buffer_key; +\& +/* Once-only initialisation of the key */ +static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT; +\& +/* Allocate the thread-specific buffer */ +void buffer_alloc(void) +{ + pthread_once(&buffer_key_once, buffer_key_alloc); + pthread_setspecific(buffer_key, malloc(100)); +} +\& +/* Return the thread-specific buffer */ +char * get_buffer(void) +{ + return (char *) pthread_getspecific(buffer_key); +} +\& +/* Allocate the key */ +static void buffer_key_alloc() +{ + pthread_key_create(&buffer_key, buffer_destroy); +} +\& +/* Free the thread-specific buffer */ +static void buffer_destroy(void * buf) +{ + free(buf); +} +.ft +.P +.RE +.fi |