ptg10805159
Section 12.6 Thread-Specific Data 449
void
thread_init(void)
{
err = pthread_key_create(&key, destructor);
}
int
threadfunc(void *arg)
{
pthread_once(&init_done, thread_init);
..
.
}
Once a key is created, we can associate thread-specific data with the key by calling
pthread_setspecific.Wecan obtain the address of the thread-specific data with
pthread_getspecific.
#include <pthread.h>
void *pthread_getspecific(pthread_key_tkey);
Returns: thread-specific data value orNULLif no value
has been associated with the key
int pthread_setspecific(pthread_key_tkey,const void *value);
Returns: 0 if OK, error number on failure
If no thread-specific data has been associated with a key,pthread_getspecificwill
return a null pointer.Wecan use this return value to determine whether we need to call
pthread_setspecific.
Example
In Figure12.11, we showed a hypothetical implementation ofgetenv.Wecame up
with a new interface to provide the same functionality,but in a thread-safe way
(Figure12.12). But what would happen if we couldn’t modify our application programs
to use the new interface? In that case, we could use thread-specific data to maintain a
per-thread copy of the data buffer used to hold the return string. This is shown in
Figure12.13.
#include <limits.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#define MAXSTRINGSZ 4096
static pthread_key_t key;
static pthread_once_t init_done = PTHREAD_ONCE_INIT;
pthread_mutex_t env_mutex = PTHREAD_MUTEX_INITIALIZER;