GNU Info

Info Node: (libc.info)Thread-Specific Data

(libc.info)Thread-Specific Data


Next: Threads and Signal Handling Prev: POSIX Semaphores Up: POSIX Threads
Enter node , (file) or (file)node

Thread-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