1PTHREAD_KEY_CREATE(P) POSIX Programmer's Manual PTHREAD_KEY_CREATE(P)
2
3
4
6 pthread_key_create - thread-specific data key creation
7
9 #include <pthread.h>
10
11 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
12
13
15 The pthread_key_create() function shall create a thread-specific data
16 key visible to all threads in the process. Key values provided by
17 pthread_key_create() are opaque objects used to locate thread-specific
18 data. Although the same key value may be used by different threads, the
19 values bound to the key by pthread_setspecific() are maintained on a
20 per-thread basis and persist for the life of the calling thread.
21
22 Upon key creation, the value NULL shall be associated with the new key
23 in all active threads. Upon thread creation, the value NULL shall be
24 associated with all defined keys in the new thread.
25
26 An optional destructor function may be associated with each key value.
27 At thread exit, if a key value has a non-NULL destructor pointer, and
28 the thread has a non-NULL value associated with that key, the value of
29 the key is set to NULL, and then the function pointed to is called with
30 the previously associated value as its sole argument. The order of
31 destructor calls is unspecified if more than one destructor exists for
32 a thread when it exits.
33
34 If, after all the destructors have been called for all non-NULL values
35 with associated destructors, there are still some non-NULL values with
36 associated destructors, then the process is repeated. If, after at
37 least {PTHREAD_DESTRUCTOR_ITERATIONS} iterations of destructor calls
38 for outstanding non-NULL values, there are still some non-NULL values
39 with associated destructors, implementations may stop calling destruc‐
40 tors, or they may continue calling destructors until no non-NULL values
41 with associated destructors exist, even though this might result in an
42 infinite loop.
43
45 If successful, the pthread_key_create() function shall store the newly
46 created key value at *key and shall return zero. Otherwise, an error
47 number shall be returned to indicate the error.
48
50 The pthread_key_create() function shall fail if:
51
52 EAGAIN The system lacked the necessary resources to create another
53 thread-specific data key, or the system-imposed limit on the
54 total number of keys per process {PTHREAD_KEYS_MAX} has been
55 exceeded.
56
57 ENOMEM Insufficient memory exists to create the key.
58
59
60 The pthread_key_create() function shall not return an error code of
61 [EINTR].
62
63 The following sections are informative.
64
66 The following example demonstrates a function that initializes a
67 thread-specific data key when it is first called, and associates a
68 thread-specific object with each calling thread, initializing this
69 object when necessary.
70
71
72 static pthread_key_t key;
73 static pthread_once_t key_once = PTHREAD_ONCE_INIT;
74
75
76 static void
77 make_key()
78 {
79 (void) pthread_key_create(&key, NULL);
80 }
81
82
83 func()
84 {
85 void *ptr;
86
87
88 (void) pthread_once(&key_once, make_key);
89 if ((ptr = pthread_getspecific(key)) == NULL) {
90 ptr = malloc(OBJECT_SIZE);
91 ...
92 (void) pthread_setspecific(key, ptr);
93 }
94 ...
95 }
96
97 Note that the key has to be initialized before pthread_getspecific() or
98 pthread_setspecific() can be used. The pthread_key_create() call could
99 either be explicitly made in a module initialization routine, or it can
100 be done implicitly by the first call to a module as in this example.
101 Any attempt to use the key before it is initialized is a programming
102 error, making the code below incorrect.
103
104
105 static pthread_key_t key;
106
107
108 func()
109 {
110 void *ptr;
111
112
113 /* KEY NOT INITIALIZED!!! THIS WON'T WORK!!! */
114 if ((ptr = pthread_getspecific(key)) == NULL &&
115 pthread_setspecific(key, NULL) != 0) {
116 pthread_key_create(&key, NULL);
117 ...
118 }
119 }
120
122 None.
123
125 Destructor Functions
126 Normally, the value bound to a key on behalf of a particular thread is
127 a pointer to storage allocated dynamically on behalf of the calling
128 thread. The destructor functions specified with pthread_key_create()
129 are intended to be used to free this storage when the thread exits.
130 Thread cancellation cleanup handlers cannot be used for this purpose
131 because thread-specific data may persist outside the lexical scope in
132 which the cancellation cleanup handlers operate.
133
134 If the value associated with a key needs to be updated during the life‐
135 time of the thread, it may be necessary to release the storage associ‐
136 ated with the old value before the new value is bound. Although the
137 pthread_setspecific() function could do this automatically, this fea‐
138 ture is not needed often enough to justify the added complexity.
139 Instead, the programmer is responsible for freeing the stale storage:
140
141
142 pthread_getspecific(key, &old);
143 new = allocate();
144 destructor(old);
145 pthread_setspecific(key, new);
146
147 Note: The above example could leak storage if run with asynchronous
148 cancellation enabled. No such problems occur in the default can‐
149 cellation state if no cancellation points occur between the get
150 and set.
151
152
153 There is no notion of a destructor-safe function. If an application
154 does not call pthread_exit() from a signal handler, or if it blocks any
155 signal whose handler may call pthread_exit() while calling async-unsafe
156 functions, all functions may be safely called from destructors.
157
158 Non-Idempotent Data Key Creation
159 There were requests to make pthread_key_create() idempotent with
160 respect to a given key address parameter. This would allow applications
161 to call pthread_key_create() multiple times for a given key address and
162 be guaranteed that only one key would be created. Doing so would
163 require the key value to be previously initialized (possibly at compile
164 time) to a known null value and would require that implicit mutual-
165 exclusion be performed based on the address and contents of the key
166 parameter in order to guarantee that exactly one key would be created.
167
168 Unfortunately, the implicit mutual-exclusion would not be limited to
169 only pthread_key_create(). On many implementations, implicit mutual-
170 exclusion would also have to be performed by pthread_getspecific() and
171 pthread_setspecific() in order to guard against using incompletely
172 stored or not-yet-visible key values. This could significantly increase
173 the cost of important operations, particularly pthread_getspecific().
174
175 Thus, this proposal was rejected. The pthread_key_create() function
176 performs no implicit synchronization. It is the responsibility of the
177 programmer to ensure that it is called exactly once per key before use
178 of the key. Several straightforward mechanisms can already be used to
179 accomplish this, including calling explicit module initialization func‐
180 tions, using mutexes, and using pthread_once(). This places no signifi‐
181 cant burden on the programmer, introduces no possibly confusing ad hoc
182 implicit synchronization mechanism, and potentially allows commonly
183 used thread-specific data operations to be more efficient.
184
186 None.
187
189 pthread_getspecific() , pthread_key_delete() , the Base Definitions
190 volume of IEEE Std 1003.1-2001, <pthread.h>
191
193 Portions of this text are reprinted and reproduced in electronic form
194 from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
195 -- Portable Operating System Interface (POSIX), The Open Group Base
196 Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of
197 Electrical and Electronics Engineers, Inc and The Open Group. In the
198 event of any discrepancy between this version and the original IEEE and
199 The Open Group Standard, the original IEEE and The Open Group Standard
200 is the referee document. The original Standard can be obtained online
201 at http://www.opengroup.org/unix/online.html .
202
203
204
205IEEE/The Open Group 2003 PTHREAD_KEY_CREATE(P)