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