1PTHREAD_KEY_CREATE(3P)     POSIX Programmer's Manual    PTHREAD_KEY_CREATE(3P)
2
3
4

PROLOG

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

NAME

12       pthread_key_create — thread-specific data key creation
13

SYNOPSIS

15       #include <pthread.h>
16
17       int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
18

DESCRIPTION

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

RETURN VALUE

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

ERRORS

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

EXAMPLES

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

APPLICATION USAGE

121       None.
122

RATIONALE

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

FUTURE DIRECTIONS

184       None.
185

SEE ALSO

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)
Impressum