38 status = pthread_once (&key_once, once_routine);
39 if (status != 0)
40 err_abort (status, "Once init");
41 value = (tsd_t*)malloc (sizeof (tsd_t));
42 if (value == NULL)
43 errno_abort ("Allocate key value");
44 status = pthread_setspecific (tsd_key, value);
45 if (status != 0)
46 err_abort (status, "Set tsd");
47 printf ("%s set tsd value %p\n", arg, value);
48 value->thread_id = pthread_self ();
49 value->string = (char*)arg;
50 value = (tsd_t*)pthread_getspecific (tsd_key);
51 printf ("%s starting...\n", value->string);
52 sleep (2);
53 value = (tsd_t*)pthread_getspecific (tsd_key);
54 printf ("%s done...\n", value->string);
55 return NULL;
56 }
57
58 void main (int argc, char *argv[])
59 {
60 pthread_t threadl, thread2;
61 int status;
62
63 status = pthread_create (
64 &thread1, NULL, thread_routine, "thread 1");
65 if (status != 0)
66 err_abort (status, "Create thread 1");
67 status = pthread_create (
68 &thread2, NULL, thread_routine, "thread 2");
69 if (status != 0)
70 err_abort (status, "Create thread 2");
71 pthread_exit (NULL);
72 }
Pthreads allows you to
When you destroy a thread-specific data key, it does not affect the current value of that key in any thread, not even in the calling thread. That means your code is completely responsible for freeing any memory that you have associated with the thread-specific data key, in all threads. Of course, any use of the deleted thread-specific data key (pthread_key_t) results in undefined behavior.
Delete thread-specific data keys only when you are sure no thread has a value for that key!
Or,.. don't destroy them at all.
You should never destroy a key while some thread still has a value for that key. Some later call to pthread_key_create, for example, might reuse the pthread_key_t identifier that had been assigned to a deleted key. When an existing thread that had set a value for the old key requests the value of the new key, it will receive the old value. The program will likely react badly to receiving this incorrect data, so you should never delete a thread-specific data key until you are sure that no existing threads have a value for that key, for example, by maintaining a "reference count" for the key, as shown in the program tsd_destructor.c. in Section 5.4.3.
Even better, don't destroy thread-specific data keys. There's rarely any need to do so, and if you try you will almost certainly run into difficulties. Few programs will require even the minimum Pthreads limit of 128 thread-specific data keys. Rarely will you use more than a few. In general, each component that uses thread-specific data will have a small number of keys each maintaining pointers to data structures that contain related data. It would take a lot of components to exhaust the available keys!
5.4.2 Using thread-specific data
int pthread_setspecific (pthread_key_t key, const void *value);
void *pthread_getspecific (pthread_key_t key);
You can use the pthread_getspecific
function to determine the thread's current value for a key, or pthread_setspecific
to change the current value. Take a look at Section 7.3.1 for ideas on using thread-specific data to adapt old libraries that rely on static data to be thread-safe.
A thread-specific data value of NULL means something special to Pthreads—do not set a thread-specific data value of NULL unless you really mean it.