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
11

NAME

13       pthread_key_create — thread-specific data key creation
14

SYNOPSIS

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

DESCRIPTION

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

RETURN VALUE

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

ERRORS

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

EXAMPLES

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

APPLICATION USAGE

120       None.
121

RATIONALE

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

FUTURE DIRECTIONS

182       None.
183

SEE ALSO

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