Copyright (C) 2000-2012 |
GNU Info (libc.info)Thread-Specific DataThread-Specific Data ==================== 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. 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 `void *' 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. For concreteness, the TSD areas can be viewed as arrays of `void *' 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. When a thread is created, its TSD area initially associates `NULL' with all keys. - Function: int pthread_key_create (pthread_key_t *KEY, void (*destr_function) (void *)) `pthread_key_create' allocates a new TSD key. The key is stored in the location pointed to by KEY. There is a limit of `PTHREAD_KEYS_MAX' on the number of keys allocated at a given time. The value initially associated with the returned key is `NULL' in all currently executing threads. The DESTR_FUNCTION argument, if not `NULL', specifies a destructor function associated with the key. When a thread terminates via `pthread_exit' or by cancellation, DESTR_FUNCTION is called on the value associated with the key in that thread. The DESTR_FUNCTION is not called if a key is deleted with `pthread_key_delete' or a value is changed with `pthread_setspecific'. The order in which destructor functions are called at thread termination time is unspecified. Before the destructor function is called, the `NULL' value is associated with the key in the current thread. A destructor function might, however, re-associate non-`NULL' values to that key or some other key. To deal with this, if after all the destructors have been called for all non-`NULL' values, there are still some non-`NULL' values with associated destructors, then the process is repeated. The LinuxThreads implementation stops the process after `PTHREAD_DESTRUCTOR_ITERATIONS' iterations, even if some non-`NULL' values with associated descriptors remain. Other implementations may loop indefinitely. `pthread_key_create' returns 0 unless `PTHREAD_KEYS_MAX' keys have already been allocated, in which case it fails and returns `EAGAIN'. - Function: int pthread_key_delete (pthread_key_t KEY) `pthread_key_delete' deallocates a TSD key. It does not check whether non-`NULL' values are associated with that key in the currently executing threads, nor call the destructor function associated with the key. If there is no such key KEY, it returns `EINVAL'. Otherwise it returns 0. - Function: int pthread_setspecific (pthread_key_t KEY, const void *POINTER) `pthread_setspecific' changes the value associated with KEY in the calling thread, storing the given POINTER instead. If there is no such key KEY, it returns `EINVAL'. Otherwise it returns 0. - Function: void * pthread_getspecific (pthread_key_t KEY) `pthread_getspecific' returns the value currently associated with KEY in the calling thread. If there is no such key KEY, it returns `NULL'. The following code fragment allocates a thread-specific array of 100 characters, with automatic reclaimation at thread exit: /* 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); } automatically generated by info2www version 1.2.2.9 |