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