pthread_mutex_destroy (3)
PROLOG
This manual page is part of the POSIX Programmer's Manual. The Linux implementation of this interface may differ (consult the corresponding Linux manual page for details of Linux behavior), or the interface may not be implemented on Linux.NAME
pthread_mutex_destroy, pthread_mutex_init --- destroy and initialize a mutexSYNOPSIS
#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 or a mutex that is referenced (for example, while being used in a pthread_cond_timedwait() or pthread_cond_wait()) by another thread 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_INITIALIZER can be used to initialize mutexes. 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. The behavior is undefined if the value specified by the mutex argument to pthread_mutex_destroy() does not refer to an initialized mutex. The behavior is undefined if the value specified by the attr argument to pthread_mutex_init() does not refer to an initialized mutex attributes object.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.ERRORS
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: - EINVAL
- The attributes object referenced by attr has the robust mutex attribute set without the process-shared attribute being set. These functions shall not return an error code of [EINTR].
The following sections are informative.
EXAMPLES
None.APPLICATION USAGE
None.RATIONALE
If an implementation detects that the value specified by the mutex argument to pthread_mutex_destroy() does not refer to an initialized mutex, it is recommended that the function should fail and report an [EINVAL] error. If an implementation detects that the value specified by the mutex argument to pthread_mutex_destroy() or pthread_mutex_init() refers to a locked mutex or a mutex that is referenced (for example, while being used in a pthread_cond_timedwait() or pthread_cond_wait()) by another thread, or detects that the value specified by the mutex argument to pthread_mutex_init() refers to an already initialized mutex, it is recommended that the function should fail and report an [EBUSY] error. If an implementation detects that the value specified by the attr argument to pthread_mutex_init() does not refer to an initialized mutex attributes object, it is recommended that the function should fail and report an [EINVAL] error.Alternate Implementations Possible
This volume of POSIX.1-2008 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 POSIX.1-2008 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 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 reference) a mutex that has already been destroyed.Tradeoff Between Error Checks and Performance Supported
Many error conditions that can occur are not required to be detected by the implementation in order to let implementations trade off performance versus degree of error checking according to the needs of their specific applications and execution environment. As a general rule, conditions caused by the system (such as insufficient memory) are required to be detected, but conditions caused by an erroneously coded application (such as failing to provide adequate synchronization to prevent a mutex from being deleted while in use) are specified to result in undefined behavior. 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 correct application under very tight performance constraints 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 POSIX.1-2008 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. When the behavior is undefined, no error number is specified to be returned on implementations that do detect the condition. This is because undefined behavior means anything can happen, which includes returning with any value (which might happen to be a valid, but different, error number). However, since the error number might be useful to application developers when diagnosing problems during application development, a recommendation is made in rationale that implementors should return a particular error number if their implementation does detect the condition.Why 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); }
-
static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER; void foo() { pthread_mutex_lock(&foo_mutex); /* Do work. */ pthread_mutex_unlock(&foo_mutex); }
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); }
Robust Mutexes
Implementations are required to provide robust mutexes for mutexes with the process-shared attribute set to PTHREAD_PROCESS_SHARED. Implementations are allowed, but not required, to provide robust mutexes when the process-shared attribute is set to PTHREAD_PROCESS_PRIVATE.FUTURE DIRECTIONS
None.SEE ALSO
pthread_mutex_getprioceiling(), pthread_mutexattr_getrobust(), pthread_mutex_lock(), pthread_mutex_timedlock(), pthread_mutexattr_getpshared() The Base Definitions volume of POSIX.1-2008, <pthread.h>COPYRIGHT
Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 7, Copyright (C) 2013 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. (This is POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) 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 www.unix.org/online.html .Any typographical or formatting errors that appear in this page are most likely to have been introduced during the conversion of the source files to man page format. To report such errors, see www.kernel.org/doc/man-pages/reporting_bugs.html .