1PTHREAD_MUTEXATTR_DESTROY(3PP)OSIX Programmer's ManuPaTlHREAD_MUTEXATTR_DESTROY(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_mutexattr_destroy, pthread_mutexattr_init -  destroy  and  ini‐
13       tialize the mutex attributes object
14

SYNOPSIS

16       #include <pthread.h>
17
18       int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
19       int pthread_mutexattr_init(pthread_mutexattr_t *attr);
20
21

DESCRIPTION

23       The   pthread_mutexattr_destroy()   function   shall  destroy  a  mutex
24       attributes object; the object becomes,  in  effect,  uninitialized.  An
25       implementation  may cause pthread_mutexattr_destroy() to set the object
26       referenced by attr to an invalid value.  A  destroyed  attr  attributes
27       object can be reinitialized using pthread_mutexattr_init(); the results
28       of otherwise referencing the object after it  has  been  destroyed  are
29       undefined.
30
31       The   pthread_mutexattr_init()   function   shall  initialize  a  mutex
32       attributes object attr with the default value for all of the attributes
33       defined by the implementation.
34
35       Results  are undefined if pthread_mutexattr_init() is called specifying
36       an already initialized attr attributes object.
37
38       After a mutex attributes object has been used to initialize one or more
39       mutexes,  any  function  affecting  the  attributes  object  (including
40       destruction) shall not affect any previously initialized mutexes.
41

RETURN VALUE

43       Upon    successful    completion,    pthread_mutexattr_destroy()    and
44       pthread_mutexattr_init()  shall return zero; otherwise, an error number
45       shall be returned to indicate the error.
46

ERRORS

48       The pthread_mutexattr_destroy() function may fail if:
49
50       EINVAL The value specified by attr is invalid.
51
52
53       The pthread_mutexattr_init() function shall fail if:
54
55       ENOMEM Insufficient memory exists to initialize  the  mutex  attributes
56              object.
57
58
59       These functions shall not return an error code of [EINTR].
60
61       The following sections are informative.
62

EXAMPLES

64       None.
65

APPLICATION USAGE

67       None.
68

RATIONALE

70       See  pthread_attr_init()  for  a  general  explanation  of  attributes.
71       Attributes objects allow  implementations  to  experiment  with  useful
72       extensions  and permit extension of this volume of IEEE Std 1003.1-2001
73       without changing the existing functions. Thus, they provide for  future
74       extensibility  of  this  volume  of IEEE Std 1003.1-2001 and reduce the
75       temptation to standardize prematurely on semantics  that  are  not  yet
76       widely implemented or understood.
77
78       Examples  of  possible  additional mutex attributes that have been dis‐
79       cussed are spin_only, limited_spin, no_spin,  recursive,  and  metered.
80       (To  explain  what  the latter attributes might mean: recursive mutexes
81       would allow for multiple  re-locking  by  the  current  owner;  metered
82       mutexes  would  transparently  keep records of queue length, wait time,
83       and so on.) Since there is not yet wide agreement on the usefulness  of
84       these  resulting  from shared implementation and usage experience, they
85       are not yet specified in this volume  of  IEEE Std 1003.1-2001.   Mutex
86       attributes  objects,  however,  make it possible to test out these con‐
87       cepts for possible standardization at a later time.
88
89   Mutex Attributes and Performance
90       Care has been taken to ensure that the  default  values  of  the  mutex
91       attributes  have  been  defined  such that mutexes initialized with the
92       defaults have simple enough semantics so that the locking and unlocking
93       can  be  done  with  the equivalent of a test-and-set instruction (plus
94       possibly a few other basic instructions).
95
96       There is at least one implementation method that can be used to  reduce
97       the cost of testing at lock-time if a mutex has non-default attributes.
98       One such method that an implementation can employ (and this can be made
99       fully  transparent  to  fully  conforming  POSIX  applications)  is  to
100       secretly pre-lock any  mutexes  that  are  initialized  to  non-default
101       attributes. Any later attempt to lock such a mutex causes the implemen‐
102       tation to branch to the "slow path" as if the mutex  were  unavailable;
103       then,  on  the  slow path, the implementation can do the "real work" to
104       lock a non-default mutex. The underlying unlock operation is more  com‐
105       plicated  since  the  implementation  never really wants to release the
106       pre-lock on this kind of mutex. This illustrates that, depending on the
107       hardware,  there  may be certain optimizations that can be used so that
108       whatever mutex attributes are considered "most frequently used" can  be
109       processed most efficiently.
110
111   Process Shared Memory and Synchronization
112       The   existence   of   memory  mapping  functions  in  this  volume  of
113       IEEE Std 1003.1-2001 leads to the possibility that an  application  may
114       allocate  the  synchronization objects from this section in memory that
115       is accessed by multiple processes (and therefore, by threads of  multi‐
116       ple processes).
117
118       In order to permit such usage, while at the same time keeping the usual
119       case (that is, usage within a single  process)  efficient,  a  process-
120       shared option has been defined.
121
122       If  an implementation supports the _POSIX_THREAD_PROCESS_SHARED option,
123       then the process-shared attribute can be used to indicate that  mutexes
124       or  condition  variables  may  be  accessed by threads of multiple pro‐
125       cesses.
126
127       The default setting of PTHREAD_PROCESS_PRIVATE has been chosen for  the
128       process-shared attribute so that the most efficient forms of these syn‐
129       chronization objects are created by default.
130
131       Synchronization   variables   that    are    initialized    with    the
132       PTHREAD_PROCESS_PRIVATE  process-shared  attribute may only be operated
133       on by threads in the process  that  initialized  them.  Synchronization
134       variables that are initialized with the PTHREAD_PROCESS_SHARED process-
135       shared attribute may be operated on by any thread in any  process  that
136       has  access  to it. In particular, these processes may exist beyond the
137       lifetime of the initializing process. For example, the  following  code
138       implements  a  simple  counting  semaphore in a mapped file that may be
139       used by many processes.
140
141
142              /* sem.h */
143              struct semaphore {
144                  pthread_mutex_t lock;
145                  pthread_cond_t nonzero;
146                  unsigned count;
147              };
148              typedef struct semaphore semaphore_t;
149
150
151              semaphore_t *semaphore_create(char *semaphore_name);
152              semaphore_t *semaphore_open(char *semaphore_name);
153              void semaphore_post(semaphore_t *semap);
154              void semaphore_wait(semaphore_t *semap);
155              void semaphore_close(semaphore_t *semap);
156
157
158              /* sem.c */
159              #include <sys/types.h>
160              #include <sys/stat.h>
161              #include <sys/mman.h>
162              #include <fcntl.h>
163              #include <pthread.h>
164              #include "sem.h"
165
166
167              semaphore_t *
168              semaphore_create(char *semaphore_name)
169              {
170              int fd;
171                  semaphore_t *semap;
172                  pthread_mutexattr_t psharedm;
173                  pthread_condattr_t psharedc;
174
175
176                  fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, 0666);
177                  if (fd < 0)
178                      return (NULL);
179                  (void) ftruncate(fd, sizeof(semaphore_t));
180                  (void) pthread_mutexattr_init(&psharedm);
181                  (void) pthread_mutexattr_setpshared(&psharedm,
182                      PTHREAD_PROCESS_SHARED);
183                  (void) pthread_condattr_init(&psharedc);
184                  (void) pthread_condattr_setpshared(&psharedc,
185                      PTHREAD_PROCESS_SHARED);
186                  semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
187                          PROT_READ | PROT_WRITE, MAP_SHARED,
188                          fd, 0);
189                  close (fd);
190                  (void) pthread_mutex_init(&semap->lock, &psharedm);
191                  (void) pthread_cond_init(&semap->nonzero, &psharedc);
192                  semap->count = 0;
193                  return (semap);
194              }
195
196
197              semaphore_t *
198              semaphore_open(char *semaphore_name)
199              {
200                  int fd;
201                  semaphore_t *semap;
202
203
204                  fd = open(semaphore_name, O_RDWR, 0666);
205                  if (fd < 0)
206                      return (NULL);
207                  semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
208                          PROT_READ | PROT_WRITE, MAP_SHARED,
209                          fd, 0);
210                  close (fd);
211                  return (semap);
212              }
213
214
215              void
216              semaphore_post(semaphore_t *semap)
217              {
218                  pthread_mutex_lock(&semap->lock);
219                  if (semap->count == 0)
220                      pthread_cond_signal(&semapx->nonzero);
221                  semap->count++;
222                  pthread_mutex_unlock(&semap->lock);
223              }
224
225
226              void
227              semaphore_wait(semaphore_t *semap)
228              {
229                  pthread_mutex_lock(&semap->lock);
230                  while (semap->count == 0)
231                      pthread_cond_wait(&semap->nonzero, &semap->lock);
232                  semap->count--;
233                  pthread_mutex_unlock(&semap->lock);
234              }
235
236
237              void
238              semaphore_close(semaphore_t *semap)
239              {
240                  munmap((void *) semap, sizeof(semaphore_t));
241              }
242
243       The following code is for three separate processes that  create,  post,
244       and  wait  on a semaphore in the file /tmp/semaphore.  Once the file is
245       created, the post and wait programs increment and decrement the  count‐
246       ing semaphore (waiting and waking as required) even though they did not
247       initialize the semaphore.
248
249
250              /* create.c */
251              #include "pthread.h"
252              #include "sem.h"
253
254
255              int
256              main()
257              {
258                  semaphore_t *semap;
259
260
261                  semap = semaphore_create("/tmp/semaphore");
262                  if (semap == NULL)
263                      exit(1);
264                  semaphore_close(semap);
265                  return (0);
266              }
267
268
269              /* post */
270              #include "pthread.h"
271              #include "sem.h"
272
273
274              int
275              main()
276              {
277                  semaphore_t *semap;
278
279
280                  semap = semaphore_open("/tmp/semaphore");
281                  if (semap == NULL)
282                      exit(1);
283                  semaphore_post(semap);
284                  semaphore_close(semap);
285                  return (0);
286              }
287
288
289              /* wait */
290              #include "pthread.h"
291              #include "sem.h"
292
293
294              int
295              main()
296              {
297                  semaphore_t *semap;
298
299
300                  semap = semaphore_open("/tmp/semaphore");
301                  if (semap == NULL)
302                      exit(1);
303                  semaphore_wait(semap);
304                  semaphore_close(semap);
305                  return (0);
306              }
307

FUTURE DIRECTIONS

309       None.
310

SEE ALSO

312       pthread_cond_destroy(),   pthread_create(),    pthread_mutex_destroy(),
313       pthread_mutexattr_destroy,    the    Base    Definitions    volume   of
314       IEEE Std 1003.1-2001, <pthread.h>
315
317       Portions of this text are reprinted and reproduced in  electronic  form
318       from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
319       -- Portable Operating System Interface (POSIX),  The  Open  Group  Base
320       Specifications  Issue  6,  Copyright  (C) 2001-2003 by the Institute of
321       Electrical and Electronics Engineers, Inc and The Open  Group.  In  the
322       event of any discrepancy between this version and the original IEEE and
323       The Open Group Standard, the original IEEE and The Open Group  Standard
324       is  the  referee document. The original Standard can be obtained online
325       at http://www.opengroup.org/unix/online.html .
326
327
328
329IEEE/The Open Group                  2003        PTHREAD_MUTEXATTR_DESTROY(3P)
Impressum