]>
Commit | Line | Data |
---|---|---|
13151ec5 AC |
1 | .\" Copyright, Xavier Leroy <Xavier.Leroy@inria.fr> |
2 | .\" Copyright 2023, Alejandro Colomar <alx@kernel.org> | |
3 | .\" | |
4 | .\" SPDX-License-Identifier: Linux-man-pages-copyleft | |
5 | .\" | |
6 | .TH pthread_key_create 3 (date) "Linux man-pages (unreleased)" | |
74235f15 AC |
7 | . |
8 | . | |
87d09778 | 9 | .SH NAME |
8a00cac7 AC |
10 | pthread_key_create, |
11 | pthread_key_delete, | |
12 | pthread_setspecific, | |
13 | pthread_getspecific | |
14 | \- | |
15 | management of thread-specific data | |
74235f15 AC |
16 | . |
17 | . | |
87d09778 | 18 | .SH SYNOPSIS |
c1c253d0 | 19 | .B #include <pthread.h> |
c6d039a3 | 20 | .P |
c1c253d0 | 21 | .BI "int pthread_key_create(pthread_key_t *" key ", void (*" destr_function ") (void *));" |
c1c253d0 | 22 | .BI "int pthread_key_delete(pthread_key_t " key ");" |
c1c253d0 | 23 | .BI "int pthread_setspecific(pthread_key_t " key ", const void *" pointer ");" |
c1c253d0 | 24 | .BI "void * pthread_getspecific(pthread_key_t " key ");" |
74235f15 AC |
25 | . |
26 | . | |
87d09778 | 27 | .SH DESCRIPTION |
8a00cac7 AC |
28 | Programs often need global or static variables |
29 | that have different values in different threads. | |
30 | Since threads share one memory space, | |
31 | this cannot be achieved with regular variables. | |
32 | Thread-specific data is the POSIX threads answer to this need. | |
c6d039a3 | 33 | .P |
8a00cac7 AC |
34 | Each thread possesses a private memory block, |
35 | the thread-specific data area, | |
36 | or TSD area for short. | |
37 | This area is indexed by TSD keys. | |
38 | The TSD area associates values of type \fBvoid *\fP to TSD keys. | |
39 | TSD keys are common to all threads, | |
40 | but the value associated with a given TSD key | |
87d09778 | 41 | can be different in each thread. |
c6d039a3 | 42 | .P |
8a00cac7 AC |
43 | For concreteness, |
44 | the TSD areas can be viewed as arrays of \fBvoid *\fP pointers, | |
45 | TSD keys as integer indices into these arrays, | |
46 | and the value of a TSD key | |
47 | as the value of the corresponding array element in the calling thread. | |
c6d039a3 | 48 | .P |
8a00cac7 AC |
49 | When a thread is created, |
50 | its TSD area initially associates \fBNULL\fP with all keys. | |
c6d039a3 | 51 | .P |
8a00cac7 AC |
52 | \fBpthread_key_create\fP allocates a new TSD key. |
53 | The key is stored in the location pointed to by \fIkey\fP. | |
54 | There is a limit of \fBPTHREAD_KEYS_MAX\fP | |
55 | on the number of keys allocated at a given time. | |
56 | The value initially associated with the returned key | |
57 | is \fBNULL\fP in all currently executing threads. | |
c6d039a3 | 58 | .P |
8a00cac7 AC |
59 | The \fIdestr_function\fP argument, |
60 | if not \fBNULL\fP, | |
61 | specifies a destructor function associated with the key. | |
ee7b1c77 | 62 | When a thread terminates via \fBpthread_exit\fP or by cancelation, |
8a00cac7 AC |
63 | \fIdestr_function\fP is called with arguments |
64 | the value associated with the key in that thread. | |
65 | The \fIdestr_function\fP is not called if that value is \fBNULL\fP. | |
66 | The order in which destructor functions are called at thread termination time | |
67 | is unspecified. | |
c6d039a3 | 68 | .P |
8a00cac7 AC |
69 | Before the destructor function is called, |
70 | the \fBNULL\fP value is associated with the key in the current thread. | |
71 | A destructor function might, | |
72 | however, | |
73 | re-associate non-\fBNULL\fP values to that key or some other key. | |
74 | To deal with this, | |
75 | if after all the destructors have been called | |
76 | for all non-\fBNULL\fP values, | |
77 | there are still some non-\fBNULL\fP values with associated destructors, | |
78 | then the process is repeated. | |
128a3ae3 | 79 | The glibc implementation stops the process |
8a00cac7 AC |
80 | after \fBPTHREAD_DESTRUCTOR_ITERATIONS\fP iterations, |
81 | even if some non-\fBNULL\fP values with associated descriptors remain. | |
82 | Other implementations may loop indefinitely. | |
c6d039a3 | 83 | .P |
8a00cac7 AC |
84 | \fBpthread_key_delete\fP deallocates a TSD key. |
85 | It does not check | |
86 | whether non-\fBNULL\fP values are associated with that key | |
87 | in the currently executing threads, | |
88 | nor call the destructor function associated with the key. | |
c6d039a3 | 89 | .P |
8a00cac7 AC |
90 | \fBpthread_setspecific\fP changes the value |
91 | associated with \fIkey\fP in the calling thread, | |
92 | storing the given \fIpointer\fP instead. | |
c6d039a3 | 93 | .P |
8a00cac7 AC |
94 | \fBpthread_getspecific\fP returns the value |
95 | currently associated with \fIkey\fP in the calling thread. | |
74235f15 AC |
96 | . |
97 | . | |
87d09778 | 98 | .SH "RETURN VALUE" |
8a00cac7 AC |
99 | \fBpthread_key_create\fP, |
100 | \fBpthread_key_delete\fP, | |
101 | and \fBpthread_setspecific\fP | |
102 | return 0 on success and a non-zero error code on failure. | |
103 | If successful, | |
104 | \fBpthread_key_create\fP stores the newly allocated key | |
105 | in the location pointed to by its \fIkey\fP argument. | |
c6d039a3 | 106 | .P |
8a00cac7 AC |
107 | \fBpthread_getspecific\fP returns |
108 | the value associated with \fIkey\fP on success, | |
109 | and \fBNULL\fP on error. | |
74235f15 AC |
110 | . |
111 | . | |
87d09778 | 112 | .SH ERRORS |
c1c253d0 | 113 | \fBpthread_key_create\fP returns the following error code on error: |
87d09778 AC |
114 | .RS |
115 | .TP | |
c1c253d0 | 116 | \fBEAGAIN\fP |
8a00cac7 | 117 | \fBPTHREAD_KEYS_MAX\fP keys are already allocated. |
87d09778 | 118 | .RE |
c6d039a3 | 119 | .P |
8a00cac7 AC |
120 | \fBpthread_key_delete\fP and \fBpthread_setspecific\fP return |
121 | the following error code on error: | |
87d09778 AC |
122 | .RS |
123 | .TP | |
c1c253d0 | 124 | \fBEINVAL\fP |
8a00cac7 | 125 | \fIkey\fP is not a valid, allocated TSD key. |
87d09778 | 126 | .RE |
c6d039a3 | 127 | .P |
c1c253d0 | 128 | \fBpthread_getspecific\fP returns \fBNULL\fP if \fIkey\fP is not a valid, |
87d09778 | 129 | allocated TSD key. |
74235f15 AC |
130 | . |
131 | . | |
87d09778 AC |
132 | .SH "SEE ALSO" |
133 | pthread_create(3), pthread_exit(3), pthread_testcancel(3). | |
74235f15 AC |
134 | . |
135 | . | |
87d09778 | 136 | .SH EXAMPLE |
8a00cac7 AC |
137 | The following code fragment |
138 | allocates a thread-specific array of 100 characters, | |
30991417 | 139 | with automatic reclamation at thread exit: |
c6d039a3 | 140 | .P |
87d09778 AC |
141 | .RS |
142 | .ft 3 | |
143 | .nf | |
144 | .sp | |
145 | /* Key for the thread-specific buffer */ | |
146 | static pthread_key_t buffer_key; | |
74235f15 | 147 | \& |
87d09778 AC |
148 | /* Once-only initialisation of the key */ |
149 | static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT; | |
74235f15 | 150 | \& |
87d09778 AC |
151 | /* Allocate the thread-specific buffer */ |
152 | void buffer_alloc(void) | |
153 | { | |
154 | pthread_once(&buffer_key_once, buffer_key_alloc); | |
155 | pthread_setspecific(buffer_key, malloc(100)); | |
156 | } | |
74235f15 | 157 | \& |
87d09778 AC |
158 | /* Return the thread-specific buffer */ |
159 | char * get_buffer(void) | |
160 | { | |
161 | return (char *) pthread_getspecific(buffer_key); | |
162 | } | |
74235f15 | 163 | \& |
87d09778 AC |
164 | /* Allocate the key */ |
165 | static void buffer_key_alloc() | |
166 | { | |
167 | pthread_key_create(&buffer_key, buffer_destroy); | |
168 | } | |
74235f15 | 169 | \& |
87d09778 AC |
170 | /* Free the thread-specific buffer */ |
171 | static void buffer_destroy(void * buf) | |
172 | { | |
173 | free(buf); | |
174 | } | |
175 | .ft | |
c6d039a3 | 176 | .P |
87d09778 AC |
177 | .RE |
178 | .fi |