The program creates a
FIGURE 5.2
5.4.1 Creating thread-specific data
pthread_key_t key;
int pthread_key_create (
pthread_key_t *key,
void (*destructor)(void *));
int pthread_key_delete (pthread_key_t key);
A thread-specific data key is represented in your program by a variable of type pthread_key_t
. Like most Pthreads types, pthread_key_t is
If you need to create a thread-specific data key later, you have to ensure that pthread_key_create is called only once for each pthread_key_t variable. That's because if you create a key twice, you are really creating two different keys. The second key will overwrite the first, which will be lost forever along with the values any threads might have set for the first key.
When you can't add code to main, the easiest way to ensure that a thread-specific data key is created only once is to use pthread_once
, the one-time initialization function, as shown in the following program, tsd_once.c.
7-10 The tsd_t
structure is used to contain per-thread data. Each thread allocates a private tsd_t
structure, and stores a pointer to that structure as its value for the thread-specific data key tsd_key
. The thread_id member holds the thread's identifier (pthread_t
), and the string member holds the pointer to a "name" string for the thread. The variable tsd_key
holds the thread-specific data key used to access the tsd_t
structures.
19-27 One-time initialization (pthread_once
) is used to ensure that the key tsd_key is created before the first access.
33-56 The threads begin in the thread start function thread_routine. The argument (arg) is a pointer to a character string naming the thread. Each thread calls pthread_once to ensure that the thread-specific data key has been created. The thread then allocates a tsd_t structure, initializes the thread_id member with the thread's identifier, and copies its argument to the string member.
The thread gets the current thread-specific data value by calling pthread_ getspecific, and prints a message using the thread's name. It then sleeps for a few seconds and prints another message to demonstrate that the thread-specific data value remains the same, even though another thread has assigned a different tsd_t structure address to the same thread-specific data key.
■ tsd_once.c
1 #include
2 #include "errors.h"
3
4 /*
5 * Structure used as the value for thread-specific data key.
6 */
7 typedef struct tsd_tag {
8 pthread_t thread_id;
9 char *string;
10 } tsd_t;
11
12 pthread_key_t tsd_key; /* Thread-specific data key */
13 pthread_once_t key_once = PTHREAD_ONCE_INIT; 14
15 /*
16 * One-time initialization routine used with the pthread_once
17 * control block.
18 */
19 void once_routine (void)
20 {
21 int status;
22
23 printf ("initializing key\n");
24 status = pthread_key_create (&tsd_key, NULL);
25 if (status != 0)
26 err_abort (status, "Create key");
27 }
28
29 /*
30 * Thread start routine that uses pthread_once to dynamically
31 * create a thread-specific data key.
32 */
33 void *thread_routine (void *arg)
34 {
35 tsd_t *value;
36 int status;
37