1PTHREAD_MUTEXATTR_DESTROY(P)POSIX Programmer's ManuaPlTHREAD_MUTEXATTR_DESTROY(P)
2
3
4
6 pthread_mutexattr_destroy, pthread_mutexattr_init - destroy and ini‐
7 tialize the mutex attributes object
8
10 #include <pthread.h>
11
12 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
13 int pthread_mutexattr_init(pthread_mutexattr_t *attr);
14
15
17 The pthread_mutexattr_destroy() function shall destroy a mutex
18 attributes object; the object becomes, in effect, uninitialized. An
19 implementation may cause pthread_mutexattr_destroy() to set the object
20 referenced by attr to an invalid value. A destroyed attr attributes
21 object can be reinitialized using pthread_mutexattr_init(); the results
22 of otherwise referencing the object after it has been destroyed are
23 undefined.
24
25 The pthread_mutexattr_init() function shall initialize a mutex
26 attributes object attr with the default value for all of the attributes
27 defined by the implementation.
28
29 Results are undefined if pthread_mutexattr_init() is called specifying
30 an already initialized attr attributes object.
31
32 After a mutex attributes object has been used to initialize one or more
33 mutexes, any function affecting the attributes object (including
34 destruction) shall not affect any previously initialized mutexes.
35
37 Upon successful completion, pthread_mutexattr_destroy() and
38 pthread_mutexattr_init() shall return zero; otherwise, an error number
39 shall be returned to indicate the error.
40
42 The pthread_mutexattr_destroy() function may fail if:
43
44 EINVAL The value specified by attr is invalid.
45
46
47 The pthread_mutexattr_init() function shall fail if:
48
49 ENOMEM Insufficient memory exists to initialize the mutex attributes
50 object.
51
52
53 These functions shall not return an error code of [EINTR].
54
55 The following sections are informative.
56
58 None.
59
61 None.
62
64 See pthread_attr_init() for a general explanation of attributes.
65 Attributes objects allow implementations to experiment with useful
66 extensions and permit extension of this volume of IEEE Std 1003.1-2001
67 without changing the existing functions. Thus, they provide for future
68 extensibility of this volume of IEEE Std 1003.1-2001 and reduce the
69 temptation to standardize prematurely on semantics that are not yet
70 widely implemented or understood.
71
72 Examples of possible additional mutex attributes that have been dis‐
73 cussed are spin_only, limited_spin, no_spin, recursive, and metered.
74 (To explain what the latter attributes might mean: recursive mutexes
75 would allow for multiple re-locking by the current owner; metered
76 mutexes would transparently keep records of queue length, wait time,
77 and so on.) Since there is not yet wide agreement on the usefulness of
78 these resulting from shared implementation and usage experience, they
79 are not yet specified in this volume of IEEE Std 1003.1-2001. Mutex
80 attributes objects, however, make it possible to test out these con‐
81 cepts for possible standardization at a later time.
82
83 Mutex Attributes and Performance
84 Care has been taken to ensure that the default values of the mutex
85 attributes have been defined such that mutexes initialized with the
86 defaults have simple enough semantics so that the locking and unlocking
87 can be done with the equivalent of a test-and-set instruction (plus
88 possibly a few other basic instructions).
89
90 There is at least one implementation method that can be used to reduce
91 the cost of testing at lock-time if a mutex has non-default attributes.
92 One such method that an implementation can employ (and this can be made
93 fully transparent to fully conforming POSIX applications) is to
94 secretly pre-lock any mutexes that are initialized to non-default
95 attributes. Any later attempt to lock such a mutex causes the implemen‐
96 tation to branch to the "slow path" as if the mutex were unavailable;
97 then, on the slow path, the implementation can do the "real work" to
98 lock a non-default mutex. The underlying unlock operation is more com‐
99 plicated since the implementation never really wants to release the
100 pre-lock on this kind of mutex. This illustrates that, depending on the
101 hardware, there may be certain optimizations that can be used so that
102 whatever mutex attributes are considered "most frequently used" can be
103 processed most efficiently.
104
105 Process Shared Memory and Synchronization
106 The existence of memory mapping functions in this volume of
107 IEEE Std 1003.1-2001 leads to the possibility that an application may
108 allocate the synchronization objects from this section in memory that
109 is accessed by multiple processes (and therefore, by threads of multi‐
110 ple processes).
111
112 In order to permit such usage, while at the same time keeping the usual
113 case (that is, usage within a single process) efficient, a process-
114 shared option has been defined.
115
116 If an implementation supports the _POSIX_THREAD_PROCESS_SHARED option,
117 then the process-shared attribute can be used to indicate that mutexes
118 or condition variables may be accessed by threads of multiple pro‐
119 cesses.
120
121 The default setting of PTHREAD_PROCESS_PRIVATE has been chosen for the
122 process-shared attribute so that the most efficient forms of these syn‐
123 chronization objects are created by default.
124
125 Synchronization variables that are initialized with the
126 PTHREAD_PROCESS_PRIVATE process-shared attribute may only be operated
127 on by threads in the process that initialized them. Synchronization
128 variables that are initialized with the PTHREAD_PROCESS_SHARED process-
129 shared attribute may be operated on by any thread in any process that
130 has access to it. In particular, these processes may exist beyond the
131 lifetime of the initializing process. For example, the following code
132 implements a simple counting semaphore in a mapped file that may be
133 used by many processes.
134
135
136 /* sem.h */
137 struct semaphore {
138 pthread_mutex_t lock;
139 pthread_cond_t nonzero;
140 unsigned count;
141 };
142 typedef struct semaphore semaphore_t;
143
144
145 semaphore_t *semaphore_create(char *semaphore_name);
146 semaphore_t *semaphore_open(char *semaphore_name);
147 void semaphore_post(semaphore_t *semap);
148 void semaphore_wait(semaphore_t *semap);
149 void semaphore_close(semaphore_t *semap);
150
151
152 /* sem.c */
153 #include <sys/types.h>
154 #include <sys/stat.h>
155 #include <sys/mman.h>
156 #include <fcntl.h>
157 #include <pthread.h>
158 #include "sem.h"
159
160
161 semaphore_t *
162 semaphore_create(char *semaphore_name)
163 {
164 int fd;
165 semaphore_t *semap;
166 pthread_mutexattr_t psharedm;
167 pthread_condattr_t psharedc;
168
169
170 fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, 0666);
171 if (fd < 0)
172 return (NULL);
173 (void) ftruncate(fd, sizeof(semaphore_t));
174 (void) pthread_mutexattr_init(&psharedm);
175 (void) pthread_mutexattr_setpshared(&psharedm,
176 PTHREAD_PROCESS_SHARED);
177 (void) pthread_condattr_init(&psharedc);
178 (void) pthread_condattr_setpshared(&psharedc,
179 PTHREAD_PROCESS_SHARED);
180 semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
181 PROT_READ | PROT_WRITE, MAP_SHARED,
182 fd, 0);
183 close (fd);
184 (void) pthread_mutex_init(&semap->lock, &psharedm);
185 (void) pthread_cond_init(&semap->nonzero, &psharedc);
186 semap->count = 0;
187 return (semap);
188 }
189
190
191 semaphore_t *
192 semaphore_open(char *semaphore_name)
193 {
194 int fd;
195 semaphore_t *semap;
196
197
198 fd = open(semaphore_name, O_RDWR, 0666);
199 if (fd < 0)
200 return (NULL);
201 semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
202 PROT_READ | PROT_WRITE, MAP_SHARED,
203 fd, 0);
204 close (fd);
205 return (semap);
206 }
207
208
209 void
210 semaphore_post(semaphore_t *semap)
211 {
212 pthread_mutex_lock(&semap->lock);
213 if (semap->count == 0)
214 pthread_cond_signal(&semapx->nonzero);
215 semap->count++;
216 pthread_mutex_unlock(&semap->lock);
217 }
218
219
220 void
221 semaphore_wait(semaphore_t *semap)
222 {
223 pthread_mutex_lock(&semap->lock);
224 while (semap->count == 0)
225 pthread_cond_wait(&semap->nonzero, &semap->lock);
226 semap->count--;
227 pthread_mutex_unlock(&semap->lock);
228 }
229
230
231 void
232 semaphore_close(semaphore_t *semap)
233 {
234 munmap((void *) semap, sizeof(semaphore_t));
235 }
236
237 The following code is for three separate processes that create, post,
238 and wait on a semaphore in the file /tmp/semaphore. Once the file is
239 created, the post and wait programs increment and decrement the count‐
240 ing semaphore (waiting and waking as required) even though they did not
241 initialize the semaphore.
242
243
244 /* create.c */
245 #include "pthread.h"
246 #include "sem.h"
247
248
249 int
250 main()
251 {
252 semaphore_t *semap;
253
254
255 semap = semaphore_create("/tmp/semaphore");
256 if (semap == NULL)
257 exit(1);
258 semaphore_close(semap);
259 return (0);
260 }
261
262
263 /* post */
264 #include "pthread.h"
265 #include "sem.h"
266
267
268 int
269 main()
270 {
271 semaphore_t *semap;
272
273
274 semap = semaphore_open("/tmp/semaphore");
275 if (semap == NULL)
276 exit(1);
277 semaphore_post(semap);
278 semaphore_close(semap);
279 return (0);
280 }
281
282
283 /* wait */
284 #include "pthread.h"
285 #include "sem.h"
286
287
288 int
289 main()
290 {
291 semaphore_t *semap;
292
293
294 semap = semaphore_open("/tmp/semaphore");
295 if (semap == NULL)
296 exit(1);
297 semaphore_wait(semap);
298 semaphore_close(semap);
299 return (0);
300 }
301
303 None.
304
306 pthread_cond_destroy() , pthread_create() , pthread_mutex_destroy() ,
307 pthread_mutexattr_destroy , the Base Definitions volume of
308 IEEE Std 1003.1-2001, <pthread.h>
309
311 Portions of this text are reprinted and reproduced in electronic form
312 from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
313 -- Portable Operating System Interface (POSIX), The Open Group Base
314 Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of
315 Electrical and Electronics Engineers, Inc and The Open Group. In the
316 event of any discrepancy between this version and the original IEEE and
317 The Open Group Standard, the original IEEE and The Open Group Standard
318 is the referee document. The original Standard can be obtained online
319 at http://www.opengroup.org/unix/online.html .
320
321
322
323IEEE/The Open Group 2003 PTHREAD_MUTEXATTR_DESTROY(P)