trusty (3) pthread_mutexattr_init.3posix.gz

Provided by: manpages-posix-dev_2.16-1_all bug

NAME

       pthread_mutexattr_destroy, pthread_mutexattr_init - destroy and initialize the mutex attributes object

SYNOPSIS

       #include <pthread.h>

       int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
       int pthread_mutexattr_init(pthread_mutexattr_t *attr);

DESCRIPTION

       The  pthread_mutexattr_destroy() function shall destroy a mutex attributes object; the object becomes, in
       effect, uninitialized.  An  implementation  may  cause  pthread_mutexattr_destroy()  to  set  the  object
       referenced  by  attr  to  an invalid value. A destroyed attr attributes object can be reinitialized using
       pthread_mutexattr_init(); the results of otherwise referencing the object after it has been destroyed are
       undefined.

       The  pthread_mutexattr_init()  function  shall initialize a mutex attributes object attr with the default
       value for all of the attributes defined by the implementation.

       Results are undefined if pthread_mutexattr_init()  is  called  specifying  an  already  initialized  attr
       attributes object.

       After  a  mutex attributes object has been used to initialize one or more mutexes, any function affecting
       the attributes object (including destruction) shall not affect any previously initialized mutexes.

RETURN VALUE

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

ERRORS

       The pthread_mutexattr_destroy() function may fail if:

       EINVAL The value specified by attr is invalid.

       The pthread_mutexattr_init() function shall fail if:

       ENOMEM Insufficient memory exists to initialize the mutex attributes object.

       These functions shall not return an error code of [EINTR].

       The following sections are informative.

EXAMPLES

       None.

APPLICATION USAGE

       None.

RATIONALE

       See   pthread_attr_init()   for   a   general   explanation  of  attributes.   Attributes  objects  allow
       implementations  to  experiment  with  useful  extensions  and  permit  extension  of  this   volume   of
       IEEE Std 1003.1-2001 without changing the existing functions. Thus, they provide for future extensibility
       of this volume of IEEE Std 1003.1-2001 and reduce the temptation to standardize prematurely on  semantics
       that are not yet widely implemented or understood.

       Examples  of  possible  additional mutex attributes that have been discussed are spin_only, limited_spin,
       no_spin, recursive, and metered. (To explain what the latter attributes  might  mean:  recursive  mutexes
       would  allow  for  multiple  re-locking  by  the  current owner; metered mutexes would transparently keep
       records of queue length, wait time, and so on.) Since there is not yet wide agreement on  the  usefulness
       of  these  resulting  from shared implementation and usage experience, they are not yet specified in this
       volume of IEEE Std 1003.1-2001.  Mutex attributes objects, however, make it possible to  test  out  these
       concepts for possible standardization at a later time.

   Mutex Attributes and Performance
       Care has been taken to ensure that the default values of the mutex attributes have been defined such that
       mutexes initialized with the defaults have simple enough semantics so that the locking and unlocking  can
       be done with the equivalent of a test-and-set instruction (plus possibly a few other basic instructions).

       There  is  at least one implementation method that can be used to reduce the cost of testing at lock-time
       if a mutex has non-default attributes. One such method that an implementation can employ (and this can be
       made  fully  transparent to fully conforming POSIX applications) is to secretly pre-lock any mutexes that
       are initialized  to  non-default  attributes.  Any  later  attempt  to  lock  such  a  mutex  causes  the
       implementation to branch to the "slow path" as if the mutex were unavailable; then, on the slow path, the
       implementation can do the "real work" to lock a non-default mutex. The  underlying  unlock  operation  is
       more  complicated  since  the  implementation  never really wants to release the pre-lock on this kind of
       mutex. This illustrates that, depending on the hardware, there may be certain optimizations that  can  be
       used  so  that  whatever  mutex  attributes  are  considered "most frequently used" can be processed most
       efficiently.

   Process Shared Memory and Synchronization
       The existence of memory mapping functions in this volume of IEEE Std 1003.1-2001 leads to the possibility
       that an application may allocate the synchronization objects from this section in memory that is accessed
       by multiple processes (and therefore, by threads of multiple processes).

       In order to permit such usage, while at the same time keeping the usual case (that  is,  usage  within  a
       single process) efficient, a process-shared option has been defined.

       If  an implementation supports the _POSIX_THREAD_PROCESS_SHARED option, then the process-shared attribute
       can be used to indicate that mutexes or condition variables  may  be  accessed  by  threads  of  multiple
       processes.

       The  default  setting of PTHREAD_PROCESS_PRIVATE has been chosen for the process-shared attribute so that
       the most efficient forms of these synchronization objects are created by default.

       Synchronization variables that are initialized with the PTHREAD_PROCESS_PRIVATE process-shared  attribute
       may  only  be operated on by threads in the process that initialized them. Synchronization variables that
       are initialized with the PTHREAD_PROCESS_SHARED process-shared attribute may be operated on by any thread
       in any process that has access to it. In particular, these processes may exist beyond the lifetime of the
       initializing process. For example, the following code implements a simple counting semaphore in a  mapped
       file that may be used by many processes.

              /* sem.h */
              struct semaphore {
                  pthread_mutex_t lock;
                  pthread_cond_t nonzero;
                  unsigned count;
              };
              typedef struct semaphore semaphore_t;

              semaphore_t *semaphore_create(char *semaphore_name);
              semaphore_t *semaphore_open(char *semaphore_name);
              void semaphore_post(semaphore_t *semap);
              void semaphore_wait(semaphore_t *semap);
              void semaphore_close(semaphore_t *semap);

              /* sem.c */
              #include <sys/types.h>
              #include <sys/stat.h>
              #include <sys/mman.h>
              #include <fcntl.h>
              #include <pthread.h>
              #include "sem.h"

              semaphore_t *
              semaphore_create(char *semaphore_name)
              {
              int fd;
                  semaphore_t *semap;
                  pthread_mutexattr_t psharedm;
                  pthread_condattr_t psharedc;

                  fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, 0666);
                  if (fd < 0)
                      return (NULL);
                  (void) ftruncate(fd, sizeof(semaphore_t));
                  (void) pthread_mutexattr_init(&psharedm);
                  (void) pthread_mutexattr_setpshared(&psharedm,
                      PTHREAD_PROCESS_SHARED);
                  (void) pthread_condattr_init(&psharedc);
                  (void) pthread_condattr_setpshared(&psharedc,
                      PTHREAD_PROCESS_SHARED);
                  semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
                          PROT_READ | PROT_WRITE, MAP_SHARED,
                          fd, 0);
                  close (fd);
                  (void) pthread_mutex_init(&semap->lock, &psharedm);
                  (void) pthread_cond_init(&semap->nonzero, &psharedc);
                  semap->count = 0;
                  return (semap);
              }

              semaphore_t *
              semaphore_open(char *semaphore_name)
              {
                  int fd;
                  semaphore_t *semap;

                  fd = open(semaphore_name, O_RDWR, 0666);
                  if (fd < 0)
                      return (NULL);
                  semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
                          PROT_READ | PROT_WRITE, MAP_SHARED,
                          fd, 0);
                  close (fd);
                  return (semap);
              }

              void
              semaphore_post(semaphore_t *semap)
              {
                  pthread_mutex_lock(&semap->lock);
                  if (semap->count == 0)
                      pthread_cond_signal(&semapx->nonzero);
                  semap->count++;
                  pthread_mutex_unlock(&semap->lock);
              }

              void
              semaphore_wait(semaphore_t *semap)
              {
                  pthread_mutex_lock(&semap->lock);
                  while (semap->count == 0)
                      pthread_cond_wait(&semap->nonzero, &semap->lock);
                  semap->count--;
                  pthread_mutex_unlock(&semap->lock);
              }

              void
              semaphore_close(semaphore_t *semap)
              {
                  munmap((void *) semap, sizeof(semaphore_t));
              }

       The following code is for three separate processes that create, post, and wait on a semaphore in the file
       /tmp/semaphore.  Once the file is created, the  post  and  wait  programs  increment  and  decrement  the
       counting semaphore (waiting and waking as required) even though they did not initialize the semaphore.

              /* create.c */
              #include "pthread.h"
              #include "sem.h"

              int
              main()
              {
                  semaphore_t *semap;

                  semap = semaphore_create("/tmp/semaphore");
                  if (semap == NULL)
                      exit(1);
                  semaphore_close(semap);
                  return (0);
              }

              /* post */
              #include "pthread.h"
              #include "sem.h"

              int
              main()
              {
                  semaphore_t *semap;

                  semap = semaphore_open("/tmp/semaphore");
                  if (semap == NULL)
                      exit(1);
                  semaphore_post(semap);
                  semaphore_close(semap);
                  return (0);
              }

              /* wait */
              #include "pthread.h"
              #include "sem.h"

              int
              main()
              {
                  semaphore_t *semap;

                  semap = semaphore_open("/tmp/semaphore");
                  if (semap == NULL)
                      exit(1);
                  semaphore_wait(semap);
                  semaphore_close(semap);
                  return (0);
              }

FUTURE DIRECTIONS

       None.

SEE ALSO

       pthread_cond_destroy()  ,  pthread_create()  ,  pthread_mutex_destroy() , pthread_mutexattr_destroy , the
       Base Definitions volume of IEEE Std 1003.1-2001, <pthread.h>

       Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition,
       Standard  for  Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base
       Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics Engineers,
       Inc  and  The  Open Group. In the event of any discrepancy between this version and the original IEEE and
       The Open Group Standard, the original IEEE and The Open Group  Standard  is  the  referee  document.  The
       original Standard can be obtained online at http://www.opengroup.org/unix/online.html .