Unix/Linux Go Back    


Linux 2.6 - man page for pthread_mutex_destroy (linux section 3posix)

Linux & Unix Commands - Search Man Pages
Man Page or Keyword Search:   man
Select Man Page Set:       apropos Keyword Search (sections above)


PTHREAD_MUTEX_DESTROY(P)	    POSIX Programmer's Manual		 PTHREAD_MUTEX_DESTROY(P)

NAME
       pthread_mutex_destroy, pthread_mutex_init - destroy and initialize a mutex

SYNOPSIS
       #include <pthread.h>

       int pthread_mutex_destroy(pthread_mutex_t *mutex);
       int pthread_mutex_init(pthread_mutex_t *restrict mutex,
	      const pthread_mutexattr_t *restrict attr);
       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

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

       It  shall be safe to destroy an initialized mutex that is unlocked.  Attempting to destroy
       a locked mutex results in undefined behavior.

       The pthread_mutex_init() function shall initialize the  mutex  referenced  by  mutex  with
       attributes  specified by attr. If attr is NULL, the default mutex attributes are used; the
       effect shall be the same as passing the address of a default mutex attributes object. Upon
       successful initialization, the state of the mutex becomes initialized and unlocked.

       Only  mutex itself may be used for performing synchronization.  The result of referring to
       copies	of   mutex   in   calls   to	pthread_mutex_lock(),	 pthread_mutex_trylock(),
       pthread_mutex_unlock(), and pthread_mutex_destroy() is undefined.

       Attempting to initialize an already initialized mutex results in undefined behavior.

       In  cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIAL-
       IZER can be used to initialize mutexes that are statically allocated. The effect shall  be
       equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr
       specified as NULL, except that no error checks are performed.

RETURN VALUE
       If successful, the pthread_mutex_destroy() and pthread_mutex_init() functions shall return
       zero; otherwise, an error number shall be returned to indicate the error.

       The [EBUSY] and [EINVAL] error checks, if implemented, act as if they were performed imme-
       diately at the beginning of processing for the function and shall cause	an  error  return
       prior to modifying the state of the mutex specified by mutex.

ERRORS
       The pthread_mutex_destroy() function may fail if:

       EBUSY  The  implementation  has	detected  an  attempt to destroy the object referenced by
	      mutex while it is locked	or  referenced	(for  example,	while  being  used  in	a
	      pthread_cond_timedwait() or pthread_cond_wait()) by another thread.

       EINVAL The value specified by mutex is invalid.

       The pthread_mutex_init() function shall fail if:

       EAGAIN The system lacked the necessary resources (other than memory) to initialize another
	      mutex.

       ENOMEM Insufficient memory exists to initialize the mutex.

       EPERM  The caller does not have the privilege to perform the operation.

       The pthread_mutex_init() function may fail if:

       EBUSY  The implementation has detected an attempt to reinitialize the object referenced by
	      mutex, a previously initialized, but not yet destroyed, mutex.

       EINVAL The value specified by attr is invalid.

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

       The following sections are informative.

EXAMPLES
       None.

APPLICATION USAGE
       None.

RATIONALE
   Alternate Implementations Possible
       This  volume  of  IEEE Std 1003.1-2001  supports  several  alternative  implementations of
       mutexes.  An  implementation  may  store  the  lock  directly  in  the  object	of   type
       pthread_mutex_t.   Alternatively,  an  implementation  may  store the lock in the heap and
       merely store a pointer, handle, or unique ID in the mutex  object.  Either  implementation
       has  advantages	or  may  be required on certain hardware configurations. So that portable
       code can be written that is invariant to this choice, this volume of  IEEE Std 1003.1-2001
       does not define assignment or equality for this type, and it uses the term "initialize" to
       reinforce the (more restrictive) notion that the lock may actually  reside  in  the  mutex
       object itself.

       Note that this precludes an over-specification of the type of the mutex or condition vari-
       able and motivates the opaqueness of the type.

       An implementation is permitted, but not required, to have pthread_mutex_destroy() store an
       illegal	value  into  the mutex.  This may help detect erroneous programs that try to lock
       (or otherwise reference) a mutex that has already been destroyed.

   Tradeoff Between Error Checks and Performance Supported
       Many of the error checks were made optional in order to let implementations trade off per-
       formance versus degree of error checking according to the needs of their specific applica-
       tions and execution environment. As a general rule, errors or  conditions  caused  by  the
       system  (such  as  insufficient	memory)  always need to be reported, but errors due to an
       erroneously coded application (such as failing to provide adequate synchronization to pre-
       vent a mutex from being deleted while in use) are made optional.

       A  wide	range  of  implementations  is thus made possible. For example, an implementation
       intended for application debugging may implement all of the error checks, but an implemen-
       tation  running	a  single, provably correct application under very tight performance con-
       straints in an embedded computer might implement minimal checks. An  implementation  might
       even  be  provided in two versions, similar to the options that compilers provide: a full-
       checking, but slower version; and a limited-checking, but faster version. To  forbid  this
       optionality would be a disservice to users.

       By  carefully  limiting	the  use of "undefined behavior" only to things that an erroneous
       (badly coded) application might do, and by defining that resource-not-available errors are
       mandatory, this volume of IEEE Std 1003.1-2001 ensures that a fully-conforming application
       is portable across the full range of implementations, while not	forcing  all  implementa-
       tions to add overhead to check for numerous things that a correct program never does.

   Why No Limits are Defined
       Defining  symbols for the maximum number of mutexes and condition variables was considered
       but rejected because the number of these objects may change dynamically. Furthermore, many
       implementations	place  these  objects into application memory; thus, there is no explicit
       maximum.

   Static Initializers for Mutexes and Condition Variables
       Providing for static initialization of statically allocated synchronization objects allows
       modules	with  private  static  synchronization	variables to avoid runtime initialization
       tests and overhead. Furthermore, it simplifies the coding  of  self-initializing  modules.
       Such  modules  are  common  in C libraries, where for various reasons the design calls for
       self-initialization instead of requiring an explicit module initialization function to  be
       called. An example use of static initialization follows.

       Without static initialization, a self-initializing routine foo() might look as follows:

	      static pthread_once_t foo_once = PTHREAD_ONCE_INIT;
	      static pthread_mutex_t foo_mutex;

	      void foo_init()
	      {
		  pthread_mutex_init(&foo_mutex, NULL);
	      }

	      void foo()
	      {
		  pthread_once(&foo_once, foo_init);
		  pthread_mutex_lock(&foo_mutex);
		 /* Do work. */
		  pthread_mutex_unlock(&foo_mutex);
	      }

       With static initialization, the same routine could be coded as follows:

	      static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;

	      void foo()
	      {
		  pthread_mutex_lock(&foo_mutex);
		 /* Do work. */
		  pthread_mutex_unlock(&foo_mutex);
	      }

       Note  that  the static initialization both eliminates the need for the initialization test
       inside pthread_once() and the fetch of &foo_mutex to learn the address  to  be  passed  to
       pthread_mutex_lock() or pthread_mutex_unlock().

       Thus,  the  C  code  written to initialize static objects is simpler on all systems and is
       also faster on a large class of systems; those where the (entire)  synchronization  object
       can be stored in application memory.

       Yet  the  locking  performance  question  is likely to be raised for machines that require
       mutexes to be allocated out of special memory. Such machines actually have to have mutexes
       and  possibly  condition  variables  contain  pointers  to the actual hardware locks.  For
       static initialization to work on such machines,	pthread_mutex_lock()  also  has  to  test
       whether	or  not  the  pointer  to  the	actual	lock  has  been allocated. If it has not,
       pthread_mutex_lock() has to initialize it before use. The reservation  of  such	resources
       can  be	made  when  the  program is loaded, and hence return codes have not been added to
       mutex locking and condition variable waiting to indicate failure to  complete  initializa-
       tion.

       This  runtime  test in pthread_mutex_lock() would at first seem to be extra work; an extra
       test is required to see whether the pointer has been initialized. On  most  machines  this
       would actually be implemented as a fetch of the pointer, testing the pointer against zero,
       and then using the pointer if it has already been initialized. While the test  might  seem
       to  add	extra work, the extra effort of testing a register is usually negligible since no
       extra memory references are actually done. As more and more machines provide  caches,  the
       real expenses are memory references, not instructions executed.

       Alternatively,  depending  on  the machine architecture, there are often ways to eliminate
       all overhead in the most important case: on the lock operations that occur after the  lock
       has  been  initialized.	This  can  be done by shifting more overhead to the less frequent
       operation: initialization. Since out-of-line mutex allocation also means that  an  address
       has to be dereferenced to find the actual lock, one technique that is widely applicable is
       to have static initialization store a bogus value for  that  address;  in  particular,  an
       address	that  causes  a  machine  fault to occur. When such a fault occurs upon the first
       attempt to lock such a mutex, validity checks can be done, and then  the  correct  address
       for  the  actual lock can be filled in. Subsequent lock operations incur no extra overhead
       since they do not "fault".  This is merely one technique  that  can  be	used  to  support
       static  initialization, while not adversely affecting the performance of lock acquisition.
       No doubt there are other techniques that are highly machine-dependent.

       The locking overhead for machines doing out-of-line mutex allocation is thus  similar  for
       modules	being  implicitly initialized, where it is improved for those doing mutex alloca-
       tion entirely inline.  The inline case is thus made much faster, and the out-of-line  case
       is not significantly worse.

       Besides the issue of locking performance for such machines, a concern is raised that it is
       possible that threads would serialize contending for initialization locks when  attempting
       to  finish  initializing  statically  allocated	mutexes.  (Such finishing would typically
       involve taking an internal lock, allocating a structure, storing a pointer to  the  struc-
       ture  in  the  mutex,  and releasing the internal lock.) First, many implementations would
       reduce such serialization by hashing on the mutex address. Second, such serialization  can
       only  occur  a bounded number of times. In particular, it can happen at most as many times
       as there are statically allocated synchronization objects. Dynamically  allocated  objects
       would still be initialized via pthread_mutex_init() or pthread_cond_init().

       Finally,  if  none  of the above optimization techniques for out-of-line allocation yields
       sufficient performance for an application on  some  implementation,  the  application  can
       avoid  static  initialization  altogether  by  explicitly initializing all synchronization
       objects with the corresponding pthread_*_init() functions,  which  are  supported  by  all
       implementations.  An  implementation can also document the tradeoffs and advise which ini-
       tialization technique is more efficient for that particular implementation.

   Destroying Mutexes
       A mutex can be destroyed immediately after it is unlocked. For example, consider the  fol-
       lowing code:

	      struct obj {
	      pthread_mutex_t om;
		  int refcnt;
		  ...
	      };

	      obj_done(struct obj *op)
	      {
		  pthread_mutex_lock(&op->om);
		  if (--op->refcnt == 0) {
		      pthread_mutex_unlock(&op->om);
	      (A)     pthread_mutex_destroy(&op->om);
	      (B)     free(op);
		  } else
	      (C)     pthread_mutex_unlock(&op->om);
	      }

       In this case obj is reference counted and obj_done() is called whenever a reference to the
       object is dropped.  Implementations are required to allow an object to  be  destroyed  and
       freed  and  potentially unmapped (for example, lines A and B) immediately after the object
       is unlocked (line C).

FUTURE DIRECTIONS
       None.

SEE ALSO
       pthread_mutex_getprioceiling()  ,  pthread_mutex_lock()	,   pthread_mutex_timedlock()	,
       pthread_mutexattr_getpshared()  ,  the  Base  Definitions  volume of IEEE Std 1003.1-2001,
       <pthread.h>

COPYRIGHT
       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 orig-
       inal Standard can be obtained online at http://www.opengroup.org/unix/online.html .

IEEE/The Open Group			       2003			 PTHREAD_MUTEX_DESTROY(P)
Unix & Linux Commands & Man Pages : ©2000 - 2018 Unix and Linux Forums


All times are GMT -4. The time now is 05:29 AM.