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
11
13 pthread_key_create — thread-specific data key creation
14
16 #include <pthread.h>
17
18 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
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 The pthread_key_create() function shall not return an error code of
66 [EINTR].
67
68 The following sections are informative.
69
71 The following example demonstrates a function that initializes a
72 thread-specific data key when it is first called, and associates a
73 thread-specific object with each calling thread, initializing this
74 object when necessary.
75
76 static pthread_key_t key;
77 static pthread_once_t key_once = PTHREAD_ONCE_INIT;
78
79 static void
80 make_key()
81 {
82 (void) pthread_key_create(&key, NULL);
83 }
84
85 func()
86 {
87 void *ptr;
88
89 (void) pthread_once(&key_once, make_key);
90 if ((ptr = pthread_getspecific(key)) == NULL) {
91 ptr = malloc(OBJECT_SIZE);
92 ...
93 (void) pthread_setspecific(key, ptr);
94 }
95 ...
96 }
97
98 Note that the key has to be initialized before pthread_getspecific() or
99 pthread_setspecific() can be used. The pthread_key_create() call could
100 either be explicitly made in a module initialization routine, or it can
101 be done implicitly by the first call to a module as in this example.
102 Any attempt to use the key before it is initialized is a programming
103 error, making the code below incorrect.
104
105 static pthread_key_t key;
106
107 func()
108 {
109 void *ptr;
110
111 /* KEY NOT INITIALIZED!!! THIS WON'T WORK!!! */
112 if ((ptr = pthread_getspecific(key)) == NULL &&
113 pthread_setspecific(key, NULL) != 0) {
114 pthread_key_create(&key, NULL);
115 ...
116 }
117 }
118
120 None.
121
123 Destructor Functions
124 Normally, the value bound to a key on behalf of a particular thread is
125 a pointer to storage allocated dynamically on behalf of the calling
126 thread. The destructor functions specified with pthread_key_create()
127 are intended to be used to free this storage when the thread exits.
128 Thread cancellation cleanup handlers cannot be used for this purpose
129 because thread-specific data may persist outside the lexical scope in
130 which the cancellation cleanup handlers operate.
131
132 If the value associated with a key needs to be updated during the life‐
133 time of the thread, it may be necessary to release the storage associ‐
134 ated with the old value before the new value is bound. Although the
135 pthread_setspecific() function could do this automatically, this fea‐
136 ture is not needed often enough to justify the added complexity.
137 Instead, the programmer is responsible for freeing the stale storage:
138
139 pthread_getspecific(key, &old);
140 new = allocate();
141 destructor(old);
142 pthread_setspecific(key, new);
143
144 Note: The above example could leak storage if run with asynchronous
145 cancellation enabled. No such problems occur in the default
146 cancellation state if no cancellation points occur between
147 the get and set.
148
149 There is no notion of a destructor-safe function. If an application
150 does not call pthread_exit() from a signal handler, or if it blocks any
151 signal whose handler may call pthread_exit() while calling async-unsafe
152 functions, all functions may be safely called from destructors.
153
154 Non-Idempotent Data Key Creation
155 There were requests to make pthread_key_create() idempotent with
156 respect to a given key address parameter. This would allow applications
157 to call pthread_key_create() multiple times for a given key address and
158 be guaranteed that only one key would be created. Doing so would
159 require the key value to be previously initialized (possibly at compile
160 time) to a known null value and would require that implicit mutual-
161 exclusion be performed based on the address and contents of the key
162 parameter in order to guarantee that exactly one key would be created.
163
164 Unfortunately, the implicit mutual-exclusion would not be limited to
165 only pthread_key_create(). On many implementations, implicit mutual-
166 exclusion would also have to be performed by pthread_getspecific() and
167 pthread_setspecific() in order to guard against using incompletely
168 stored or not-yet-visible key values. This could significantly increase
169 the cost of important operations, particularly pthread_getspecific().
170
171 Thus, this proposal was rejected. The pthread_key_create() function
172 performs no implicit synchronization. It is the responsibility of the
173 programmer to ensure that it is called exactly once per key before use
174 of the key. Several straightforward mechanisms can already be used to
175 accomplish this, including calling explicit module initialization func‐
176 tions, using mutexes, and using pthread_once(). This places no signif‐
177 icant burden on the programmer, introduces no possibly confusing ad hoc
178 implicit synchronization mechanism, and potentially allows commonly
179 used thread-specific data operations to be more efficient.
180
182 None.
183
185 pthread_getspecific(), pthread_key_delete()
186
187 The Base Definitions volume of POSIX.1‐2008, <pthread.h>
188
190 Portions of this text are reprinted and reproduced in electronic form
191 from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
192 -- Portable Operating System Interface (POSIX), The Open Group Base
193 Specifications Issue 7, Copyright (C) 2013 by the Institute of Electri‐
194 cal and Electronics Engineers, Inc and The Open Group. (This is
195 POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In the
196 event of any discrepancy between this version and the original IEEE and
197 The Open Group Standard, the original IEEE and The Open Group Standard
198 is the referee document. The original Standard can be obtained online
199 at http://www.unix.org/online.html .
200
201 Any typographical or formatting errors that appear in this page are
202 most likely to have been introduced during the conversion of the source
203 files to man page format. To report such errors, see https://www.ker‐
204 nel.org/doc/man-pages/reporting_bugs.html .
205
206
207
208IEEE/The Open Group 2013 PTHREAD_KEY_CREATE(3P)