1PTHREAD_MUTEX_DESTROY(3P) POSIX Programmer's Manual PTHREAD_MUTEX_DESTROY(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_mutex_destroy, pthread_mutex_init — destroy and initialize a
14 mutex
15
17 #include <pthread.h>
18
19 int pthread_mutex_destroy(pthread_mutex_t *mutex);
20 int pthread_mutex_init(pthread_mutex_t *restrict mutex,
21 const pthread_mutexattr_t *restrict attr);
22 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
23
25 The pthread_mutex_destroy() function shall destroy the mutex object
26 referenced by mutex; the mutex object becomes, in effect, uninitial‐
27 ized. An implementation may cause pthread_mutex_destroy() to set the
28 object referenced by mutex to an invalid value.
29
30 A destroyed mutex object can be reinitialized using
31 pthread_mutex_init(); the results of otherwise referencing the object
32 after it has been destroyed are undefined.
33
34 It shall be safe to destroy an initialized mutex that is unlocked.
35 Attempting to destroy a locked mutex or a mutex that is referenced (for
36 example, while being used in a pthread_cond_timedwait() or
37 pthread_cond_wait()) by another thread results in undefined behavior.
38
39 The pthread_mutex_init() function shall initialize the mutex referenced
40 by mutex with attributes specified by attr. If attr is NULL, the
41 default mutex attributes are used; the effect shall be the same as
42 passing the address of a default mutex attributes object. Upon success‐
43 ful initialization, the state of the mutex becomes initialized and
44 unlocked.
45
46 Only mutex itself may be used for performing synchronization. The
47 result of referring to copies of mutex in calls to
48 pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock(),
49 and pthread_mutex_destroy() is undefined.
50
51 Attempting to initialize an already initialized mutex results in unde‐
52 fined behavior.
53
54 In cases where default mutex attributes are appropriate, the macro
55 PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes. The effect
56 shall be equivalent to dynamic initialization by a call to
57 pthread_mutex_init() with parameter attr specified as NULL, except that
58 no error checks are performed.
59
60 The behavior is undefined if the value specified by the mutex argument
61 to pthread_mutex_destroy() does not refer to an initialized mutex.
62
63 The behavior is undefined if the value specified by the attr argument
64 to pthread_mutex_init() does not refer to an initialized mutex
65 attributes object.
66
68 If successful, the pthread_mutex_destroy() and pthread_mutex_init()
69 functions shall return zero; otherwise, an error number shall be
70 returned to indicate the error.
71
73 The pthread_mutex_init() function shall fail if:
74
75 EAGAIN The system lacked the necessary resources (other than memory) to
76 initialize another mutex.
77
78 ENOMEM Insufficient memory exists to initialize the mutex.
79
80 EPERM The caller does not have the privilege to perform the operation.
81
82 The pthread_mutex_init() function may fail if:
83
84 EINVAL The attributes object referenced by attr has the robust mutex
85 attribute set without the process-shared attribute being set.
86
87 These functions shall not return an error code of [EINTR].
88
89 The following sections are informative.
90
92 None.
93
95 None.
96
98 If an implementation detects that the value specified by the mutex
99 argument to pthread_mutex_destroy() does not refer to an initialized
100 mutex, it is recommended that the function should fail and report an
101 [EINVAL] error.
102
103 If an implementation detects that the value specified by the mutex
104 argument to pthread_mutex_destroy() or pthread_mutex_init() refers to a
105 locked mutex or a mutex that is referenced (for example, while being
106 used in a pthread_cond_timedwait() or pthread_cond_wait()) by another
107 thread, or detects that the value specified by the mutex argument to
108 pthread_mutex_init() refers to an already initialized mutex, it is rec‐
109 ommended that the function should fail and report an [EBUSY] error.
110
111 If an implementation detects that the value specified by the attr argu‐
112 ment to pthread_mutex_init() does not refer to an initialized mutex
113 attributes object, it is recommended that the function should fail and
114 report an [EINVAL] error.
115
116 Alternate Implementations Possible
117 This volume of POSIX.1‐2008 supports several alternative implementa‐
118 tions of mutexes. An implementation may store the lock directly in the
119 object of type pthread_mutex_t. Alternatively, an implementation may
120 store the lock in the heap and merely store a pointer, handle, or
121 unique ID in the mutex object. Either implementation has advantages or
122 may be required on certain hardware configurations. So that portable
123 code can be written that is invariant to this choice, this volume of
124 POSIX.1‐2008 does not define assignment or equality for this type, and
125 it uses the term ``initialize'' to reinforce the (more restrictive)
126 notion that the lock may actually reside in the mutex object itself.
127
128 Note that this precludes an over-specification of the type of the mutex
129 or condition variable and motivates the opaqueness of the type.
130
131 An implementation is permitted, but not required, to have
132 pthread_mutex_destroy() store an illegal value into the mutex. This may
133 help detect erroneous programs that try to lock (or otherwise refer‐
134 ence) a mutex that has already been destroyed.
135
136 Tradeoff Between Error Checks and Performance Supported
137 Many error conditions that can occur are not required to be detected by
138 the implementation in order to let implementations trade off perfor‐
139 mance versus degree of error checking according to the needs of their
140 specific applications and execution environment. As a general rule,
141 conditions caused by the system (such as insufficient memory) are
142 required to be detected, but conditions caused by an erroneously coded
143 application (such as failing to provide adequate synchronization to
144 prevent a mutex from being deleted while in use) are specified to
145 result in undefined behavior.
146
147 A wide range of implementations is thus made possible. For example, an
148 implementation intended for application debugging may implement all of
149 the error checks, but an implementation running a single, provably cor‐
150 rect application under very tight performance constraints in an embed‐
151 ded computer might implement minimal checks. An implementation might
152 even be provided in two versions, similar to the options that compilers
153 provide: a full-checking, but slower version; and a limited-checking,
154 but faster version. To forbid this optionality would be a disservice to
155 users.
156
157 By carefully limiting the use of ``undefined behavior'' only to things
158 that an erroneous (badly coded) application might do, and by defining
159 that resource-not-available errors are mandatory, this volume of
160 POSIX.1‐2008 ensures that a fully-conforming application is portable
161 across the full range of implementations, while not forcing all imple‐
162 mentations to add overhead to check for numerous things that a correct
163 program never does. When the behavior is undefined, no error number is
164 specified to be returned on implementations that do detect the condi‐
165 tion. This is because undefined behavior means anything can happen,
166 which includes returning with any value (which might happen to be a
167 valid, but different, error number). However, since the error number
168 might be useful to application developers when diagnosing problems dur‐
169 ing application development, a recommendation is made in rationale that
170 implementors should return a particular error number if their implemen‐
171 tation does detect the condition.
172
173 Why No Limits are Defined
174 Defining symbols for the maximum number of mutexes and condition vari‐
175 ables was considered but rejected because the number of these objects
176 may change dynamically. Furthermore, many implementations place these
177 objects into application memory; thus, there is no explicit maximum.
178
179 Static Initializers for Mutexes and Condition Variables
180 Providing for static initialization of statically allocated synchro‐
181 nization objects allows modules with private static synchronization
182 variables to avoid runtime initialization tests and overhead. Further‐
183 more, it simplifies the coding of self-initializing modules. Such mod‐
184 ules are common in C libraries, where for various reasons the design
185 calls for self-initialization instead of requiring an explicit module
186 initialization function to be called. An example use of static initial‐
187 ization follows.
188
189 Without static initialization, a self-initializing routine foo() might
190 look as follows:
191
192 static pthread_once_t foo_once = PTHREAD_ONCE_INIT;
193 static pthread_mutex_t foo_mutex;
194
195 void foo_init()
196 {
197 pthread_mutex_init(&foo_mutex, NULL);
198 }
199
200 void foo()
201 {
202 pthread_once(&foo_once, foo_init);
203 pthread_mutex_lock(&foo_mutex);
204 /* Do work. */
205 pthread_mutex_unlock(&foo_mutex);
206 }
207
208 With static initialization, the same routine could be coded as follows:
209
210 static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;
211
212 void foo()
213 {
214 pthread_mutex_lock(&foo_mutex);
215 /* Do work. */
216 pthread_mutex_unlock(&foo_mutex);
217 }
218
219 Note that the static initialization both eliminates the need for the
220 initialization test inside pthread_once() and the fetch of &foo_mutex
221 to learn the address to be passed to pthread_mutex_lock() or
222 pthread_mutex_unlock().
223
224 Thus, the C code written to initialize static objects is simpler on all
225 systems and is also faster on a large class of systems; those where the
226 (entire) synchronization object can be stored in application memory.
227
228 Yet the locking performance question is likely to be raised for
229 machines that require mutexes to be allocated out of special memory.
230 Such machines actually have to have mutexes and possibly condition
231 variables contain pointers to the actual hardware locks. For static
232 initialization to work on such machines, pthread_mutex_lock() also has
233 to test whether or not the pointer to the actual lock has been allo‐
234 cated. If it has not, pthread_mutex_lock() has to initialize it before
235 use. The reservation of such resources can be made when the program is
236 loaded, and hence return codes have not been added to mutex locking and
237 condition variable waiting to indicate failure to complete initializa‐
238 tion.
239
240 This runtime test in pthread_mutex_lock() would at first seem to be
241 extra work; an extra test is required to see whether the pointer has
242 been initialized. On most machines this would actually be implemented
243 as a fetch of the pointer, testing the pointer against zero, and then
244 using the pointer if it has already been initialized. While the test
245 might seem to add extra work, the extra effort of testing a register is
246 usually negligible since no extra memory references are actually done.
247 As more and more machines provide caches, the real expenses are memory
248 references, not instructions executed.
249
250 Alternatively, depending on the machine architecture, there are often
251 ways to eliminate all overhead in the most important case: on the lock
252 operations that occur after the lock has been initialized. This can be
253 done by shifting more overhead to the less frequent operation: initial‐
254 ization. Since out-of-line mutex allocation also means that an address
255 has to be dereferenced to find the actual lock, one technique that is
256 widely applicable is to have static initialization store a bogus value
257 for that address; in particular, an address that causes a machine fault
258 to occur. When such a fault occurs upon the first attempt to lock such
259 a mutex, validity checks can be done, and then the correct address for
260 the actual lock can be filled in. Subsequent lock operations incur no
261 extra overhead since they do not ``fault''. This is merely one tech‐
262 nique that can be used to support static initialization, while not
263 adversely affecting the performance of lock acquisition. No doubt there
264 are other techniques that are highly machine-dependent.
265
266 The locking overhead for machines doing out-of-line mutex allocation is
267 thus similar for modules being implicitly initialized, where it is
268 improved for those doing mutex allocation entirely inline. The inline
269 case is thus made much faster, and the out-of-line case is not signifi‐
270 cantly worse.
271
272 Besides the issue of locking performance for such machines, a concern
273 is raised that it is possible that threads would serialize contending
274 for initialization locks when attempting to finish initializing stati‐
275 cally allocated mutexes. (Such finishing would typically involve taking
276 an internal lock, allocating a structure, storing a pointer to the
277 structure in the mutex, and releasing the internal lock.) First, many
278 implementations would reduce such serialization by hashing on the mutex
279 address. Second, such serialization can only occur a bounded number of
280 times. In particular, it can happen at most as many times as there are
281 statically allocated synchronization objects. Dynamically allocated
282 objects would still be initialized via pthread_mutex_init() or
283 pthread_cond_init().
284
285 Finally, if none of the above optimization techniques for out-of-line
286 allocation yields sufficient performance for an application on some
287 implementation, the application can avoid static initialization alto‐
288 gether by explicitly initializing all synchronization objects with the
289 corresponding pthread_*_init() functions, which are supported by all
290 implementations. An implementation can also document the tradeoffs and
291 advise which initialization technique is more efficient for that par‐
292 ticular implementation.
293
294 Destroying Mutexes
295 A mutex can be destroyed immediately after it is unlocked. For example,
296 consider the following code:
297
298 struct obj {
299 pthread_mutex_t om;
300 int refcnt;
301 ...
302 };
303
304 obj_done(struct obj *op)
305 {
306 pthread_mutex_lock(&op->om);
307 if (--op->refcnt == 0) {
308 pthread_mutex_unlock(&op->om);
309 (A) pthread_mutex_destroy(&op->om);
310 (B) free(op);
311 } else
312 (C) pthread_mutex_unlock(&op->om);
313 }
314
315 In this case obj is reference counted and obj_done() is called whenever
316 a reference to the object is dropped. Implementations are required to
317 allow an object to be destroyed and freed and potentially unmapped (for
318 example, lines A and B) immediately after the object is unlocked (line
319 C).
320
321 Robust Mutexes
322 Implementations are required to provide robust mutexes for mutexes with
323 the process-shared attribute set to PTHREAD_PROCESS_SHARED. Implementa‐
324 tions are allowed, but not required, to provide robust mutexes when the
325 process-shared attribute is set to PTHREAD_PROCESS_PRIVATE.
326
328 None.
329
331 pthread_mutex_getprioceiling(), pthread_mutexattr_getrobust(),
332 pthread_mutex_lock(), pthread_mutex_timedlock(), pthread_mutex‐
333 attr_getpshared()
334
335 The Base Definitions volume of POSIX.1‐2008, <pthread.h>
336
338 Portions of this text are reprinted and reproduced in electronic form
339 from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
340 -- Portable Operating System Interface (POSIX), The Open Group Base
341 Specifications Issue 7, Copyright (C) 2013 by the Institute of Electri‐
342 cal and Electronics Engineers, Inc and The Open Group. (This is
343 POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In the
344 event of any discrepancy between this version and the original IEEE and
345 The Open Group Standard, the original IEEE and The Open Group Standard
346 is the referee document. The original Standard can be obtained online
347 at http://www.unix.org/online.html .
348
349 Any typographical or formatting errors that appear in this page are
350 most likely to have been introduced during the conversion of the source
351 files to man page format. To report such errors, see https://www.ker‐
352 nel.org/doc/man-pages/reporting_bugs.html .
353
354
355
356IEEE/The Open Group 2013 PTHREAD_MUTEX_DESTROY(3P)