pthread_mutex_destroy man page on YellowDog

Man page or keyword search:  
man Server   18644 pages
apropos Keyword Search (all sections)
Output format
YellowDog logo
[printable version]

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, uninitial‐
       ized. 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 unde‐
       fined.

       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 success‐
       ful  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 unde‐
       fined behavior.

       In cases where default mutex  attributes	 are  appropriate,  the	 macro
       PTHREAD_MUTEX_INITIALIZER  can  be  used to initialize mutexes that are
       statically allocated. The effect shall be equivalent  to	 dynamic  ini‐
       tialization by a call to pthread_mutex_init() with parameter attr spec‐
       ified 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 immediately at the beginning of processing for the func‐
       tion 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	 exam‐
	      ple,   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 imple‐
       mentations 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 restric‐
       tive) 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 variable 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  ref‐
       erence) 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 implementa‐
       tions trade off performance versus degree of error  checking  according
       to  the needs of their specific applications 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 syn‐
       chronization  to	 prevent  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 implementation running a single, provably cor‐
       rect  application under very tight performance constraints in an embed‐
       ded 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 implementations 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	 vari‐
       ables  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 synchro‐
       nization objects allows modules	with  private  static  synchronization
       variables  to avoid runtime initialization tests and overhead. Further‐
       more, it simplifies the coding of self-initializing modules. Such  mod‐
       ules  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 initial‐
       ization 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 allo‐
       cated. 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: initial‐
       ization. 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 allocation entirely inline.  The	inline
       case is thus made much faster, and the out-of-line case is not signifi‐
       cantly 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	stati‐
       cally allocated mutexes. (Such finishing would typically involve taking
       an internal lock, allocating a structure,  storing  a  pointer  to  the
       structure  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 alto‐
       gether 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  initialization technique is more efficient for that par‐
       ticular implementation.

   Destroying Mutexes
       A mutex can be destroyed immediately after it is unlocked. For example,
       consider the following 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 original Standard can be  obtained	online
       at http://www.opengroup.org/unix/online.html .

IEEE/The Open Group		     2003	      PTHREAD_MUTEX_DESTROY(P)
[top]

List of man pages available for YellowDog

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net