1thr_keycreate(3C) Standard C Library Functions thr_keycreate(3C)
2
3
4
6 thr_keycreate, thr_keycreate_once, thr_setspecific, thr_getspecific -
7 thread-specific data functions
8
10 cc -mt [ flag... ] file... [ library... ]
11 #include <thread.h>
12
13 int thr_keycreate(thread_key_t *keyp,
14 void (*destructor)(void *));
15
16
17 int thr_keycreate_once(thread_key_t *keyp,
18 void (*destructor)(void *));
19
20
21 int thr_setspecific(thread_key_t key, void *value);
22
23
24 int thr_getspecific(thread_key_t key, void **valuep);
25
26
28 Create Key
29 In general, thread key creation allocates a key that locates data spe‐
30 cific to each thread in the process. The key is global to all threads
31 in the process, which allows each thread to bind a value to the key
32 once the key has been created. The key independently maintains specific
33 values for each binding thread. The thr_keycreate() function allocates
34 a global key namespace, pointed to by keyp, that is visible to all
35 threads in the process. Each thread is initially bound to a private
36 element of this key, which allows access to its thread-specific data.
37
38
39 Upon key creation, a new key is assigned the value NULL for all active
40 threads. Additionally, upon thread creation, all previously created
41 keys in the new thread are assigned the value NULL.
42
43
44 Optionally, a destructor function destructor can be associated with
45 each key. Upon thread exit, if a key has a non-null destructor function
46 and the thread has a non-null value associated with that key, the
47 destructor function is called with the current associated value. If
48 more than one destructor exists for a thread when it exits, the order
49 of destructor calls is unspecified.
50
51
52 An exiting thread runs with all signals blocked. All thread termination
53 functions, including thread-specific data destructor functions, are
54 called with all signals blocked.
55
56
57 The thr_keycreate_once() function is identical to the thr_keycreate()
58 function except that the key pointed to by keyp must be statically ini‐
59 tialized with the value THR_ONCE_KEY before calling thr_keycre‐
60 ate_once() and the key will be created exactly once. This is equiva‐
61 lent to using pthread_once() to call a onetime initialization function
62 that calls thr_keycreate() to create the data key.
63
64 Set Value
65 Once a key has been created, each thread can bind a new value to the
66 key using thr_setspecific(). The values are unique to the binding
67 thread and are individually maintained. These values continue for the
68 life of the calling thread.
69
70
71 Proper synchronization of key storage and access must be ensured by
72 the caller. The value argument to thr_setspecific() is generally a
73 pointer to a block of dynamically allocated memory reserved by the
74 calling thread for its own use. See EXAMPLES below.
75
76
77 At thread exit, the destructor function, which is associated at time of
78 creation, is called and it uses the specific key value as its sole
79 argument.
80
81 Get Value
82 thr_getspecific() stores the current value bound to key for the calling
83 thread into the location pointed to by valuep.
84
86 If successful, thr_keycreate(), thr_keycreate_once(), thr_setspecific()
87 and thr_getspecific() return 0. Otherwise, an error number is returned
88 to indicate the error.
89
91 If the following conditions occur, thr_keycreate() and thr_keycre‐
92 ate_once() return the corresponding error number:
93
94 EAGAIN The system lacked the necessary resources to create another
95 thread-specific data key.
96
97
98 ENOMEM Insufficient memory exists to create the key.
99
100
101
102 If the following conditions occur, thr_setspecific() returns the corre‐
103 sponding error number:
104
105 ENOMEM Insufficient memory exists to associate the value with the
106 key.
107
108
109
110 The thr_setspecific() function returns the corresponding error number:
111
112 EINVAL The key value is invalid.
113
114
116 Example 1 Call the thread-specific data from more than one thread with‐
117 out special initialization.
118
119
120 In this example, the thread-specific data in this function can be
121 called from more than one thread without special initialization. For
122 each argument passed to the executable, a thread is created and pri‐
123 vately bound to the string-value of that argument.
124
125
126 /* cc -mt thisfile.c */
127
128 #include <stdio.h>
129 #include <stdlib.h>
130 #include <string.h>
131 #include <thread.h>
132
133 void *thread_specific_data(void *);
134 void cleanup(void*);
135 #define MAX_ARGC 20
136 thread_t tid[MAX_ARGC];
137 int num_threads;
138
139 int
140 main(int argc, char *argv[]) {
141 int i;
142 num_threads = argc - 1;
143 for (i = 0; i < num_threads; i++)
144 thr_create(NULL, 0, thread_specific_data, argv[i+1], 0, &tid[i]);
145 for (i = 0; i < num_threads; i++)
146 thr_join(tid[i], NULL, NULL);
147 return (0);
148 } /* end main */
149
150 void *
151 thread_specific_data(void *arg) {
152 static thread_key_t key = THR_ONCE_KEY;
153 char *private_data = arg;
154 void *tsd = NULL;
155 void *data;
156
157 thr_keycreate_once(&key, cleanup);
158 thr_getspecific(key, &tsd);
159 if (tsd == NULL) {
160 data = malloc(strlen(private_data) + 1);
161 strcpy(data, private_data);
162 thr_setspecific(key, data);
163 thr_getspecific(key, &tsd);
164 }
165 printf("tsd for %d = %s\n", thr_self(), (char *)tsd);
166 thr_getspecific(key, &tsd);
167 printf("tsd for %d remains %s\n", thr_self(), (char *)tsd);
168 return (NULL);
169 } /* end thread_specific_data */
170
171 void
172 cleanup(void *v) {
173 /* application-specific clean-up function */
174 free(v);
175 }
176
177
179 See attributes(5) for descriptions of the following attributes:
180
181
182
183
184 ┌─────────────────────────────┬─────────────────────────────┐
185 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
186 ├─────────────────────────────┼─────────────────────────────┤
187 │Interface Stability │Committed │
188 ├─────────────────────────────┼─────────────────────────────┤
189 │MT-Level │MT-Safe │
190 └─────────────────────────────┴─────────────────────────────┘
191
193 pthread_once(3C), thr_exit(3C), attributes(5), standards(5)
194
196 The thr_getspecific() and thr_setspecific() functions can be called
197 either explicitly or implicitly from a thread-specific data destructor
198 function. Calling thr_setspecific() from a destructor can result in
199 lost storage or infinite loops.
200
201
202
203SunOS 5.11 2 Nov 2007 thr_keycreate(3C)