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

DESCRIPTION

22       The   pthread_mutexattr_destroy()   function   shall  destroy  a  mutex
23       attributes object; the object becomes,  in  effect,  uninitialized.  An
24       implementation  may cause pthread_mutexattr_destroy() to set the object
25       referenced by attr to an invalid value.
26
27       A  destroyed  attr  attributes  object  can  be   reinitialized   using
28       pthread_mutexattr_init();  the  results  of  otherwise  referencing the
29       object after it has been destroyed are 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
42       The  behavior  is undefined if the value specified by the attr argument
43       to pthread_mutexattr_destroy() does not refer to an  initialized  mutex
44       attributes object.
45

RETURN VALUE

47       Upon    successful    completion,    pthread_mutexattr_destroy()    and
48       pthread_mutexattr_init() shall return zero; otherwise, an error  number
49       shall be returned to indicate the error.
50

ERRORS

52       The pthread_mutexattr_init() function shall fail if:
53
54       ENOMEM Insufficient  memory  exists  to initialize the mutex attributes
55              object.
56
57       These functions shall not return an error code of [EINTR].
58
59       The following sections are informative.
60

EXAMPLES

62       None.
63

APPLICATION USAGE

65       None.
66

RATIONALE

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

FUTURE DIRECTIONS

295       None.
296

SEE ALSO

298       pthread_cond_destroy(), pthread_create(), pthread_mutex_destroy()
299
300       The Base Definitions volume of POSIX.1‐2017, <pthread.h>
301
303       Portions of this text are reprinted and reproduced in  electronic  form
304       from  IEEE Std 1003.1-2017, Standard for Information Technology -- Por‐
305       table Operating System Interface (POSIX), The Open Group Base  Specifi‐
306       cations  Issue  7, 2018 Edition, Copyright (C) 2018 by the Institute of
307       Electrical and Electronics Engineers, Inc and The Open Group.   In  the
308       event of any discrepancy between this version and the original IEEE and
309       The Open Group Standard, the original IEEE and The Open Group  Standard
310       is  the  referee document. The original Standard can be obtained online
311       at http://www.opengroup.org/unix/online.html .
312
313       Any typographical or formatting errors that appear  in  this  page  are
314       most likely to have been introduced during the conversion of the source
315       files to man page format. To report such errors,  see  https://www.ker
316       nel.org/doc/man-pages/reporting_bugs.html .
317
318
319
320IEEE/The Open Group                  2017        PTHREAD_MUTEXATTR_DESTROY(3P)
Impressum