A mutex is a MUTual EXclusion device, and is useful for protecting shared data structures from concurrent modifications, and implementing critical sections and monitors.
A mutex has two possible states: unlocked (not owned by any thread), and locked (owned by one thread). A mutex can never be owned by two different threads simultaneously. A thread attempting to lock a mutex that is already locked by another thread is suspended until the owning thread unlocks the mutex first.
None of the mutex functions is a cancellation point, not even
pthread_mutex_lock
, in spite of the fact that it can suspend a
thread for arbitrary durations. This way, the status of mutexes at
cancellation points is predictable, allowing cancellation handlers to
unlock precisely those mutexes that need to be unlocked before the
thread stops executing. Consequently, threads using deferred
cancellation should never hold a mutex for extended periods of time.
It is not safe to call mutex functions from a signal handler. In
particular, calling pthread_mutex_lock
or
pthread_mutex_unlock
from a signal handler may deadlock the
calling thread.
pthread_mutex_init
initializes the mutex object pointed to by
mutex according to the mutex attributes specified in mutexattr.
If mutexattr is NULL
, default attributes are used instead.
The LinuxThreads implementation supports only one mutex attribute, the mutex kind, which is either "fast", "recursive", or "error checking". The kind of a mutex determines whether it can be locked again by a thread that already owns it. The default kind is "fast".
Variables of type pthread_mutex_t
can also be initialized
statically, using the constants PTHREAD_MUTEX_INITIALIZER
(for
fast mutexes), PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
(for
recursive mutexes), and PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
(for error checking mutexes).
pthread_mutex_init
always returns 0.
pthread_mutex_lock
locks the given mutex. If the mutex is
currently unlocked, it becomes locked and owned by the calling thread,
and pthread_mutex_lock
returns immediately. If the mutex is
already locked by another thread, pthread_mutex_lock
suspends the
calling thread until the mutex is unlocked.
If the mutex is already locked by the calling thread, the behavior of
pthread_mutex_lock
depends on the kind of the mutex. If the mutex
is of the "fast" kind, the calling thread is suspended. It will
remain suspended forever, because no other thread can unlock the mutex.
If the mutex is of the "error checking" kind, pthread_mutex_lock
returns immediately with the error code EDEADLK
. If the mutex is
of the "recursive" kind, pthread_mutex_lock
succeeds and
returns immediately, recording the number of times the calling thread
has locked the mutex. An equal number of pthread_mutex_unlock
operations must be performed before the mutex returns to the unlocked
state.
pthread_mutex_trylock
behaves identically to
pthread_mutex_lock
, except that it does not block the calling
thread if the mutex is already locked by another thread (or by the
calling thread in the case of a "fast" mutex). Instead,
pthread_mutex_trylock
returns immediately with the error code
EBUSY
.
pthread_mutex_unlock
unlocks the given mutex. The mutex is
assumed to be locked and owned by the calling thread on entrance to
pthread_mutex_unlock
. If the mutex is of the "fast" kind,
pthread_mutex_unlock
always returns it to the unlocked state. If
it is of the "recursive" kind, it decrements the locking count of the
mutex (number of pthread_mutex_lock
operations performed on it by
the calling thread), and only when this count reaches zero is the mutex
actually unlocked.
On "error checking" mutexes, pthread_mutex_unlock
actually
checks at run-time that the mutex is locked on entrance, and that it was
locked by the same thread that is now calling
pthread_mutex_unlock
. If these conditions are not met,
pthread_mutex_unlock
returns EPERM
, and the mutex remains
unchanged. "Fast" and "recursive" mutexes perform no such checks,
thus allowing a locked mutex to be unlocked by a thread other than its
owner. This is non-portable behavior and must not be relied upon.
pthread_mutex_destroy
destroys a mutex object, freeing the
resources it might hold. The mutex must be unlocked on entrance. In the
LinuxThreads implementation, no resources are associated with mutex
objects, thus pthread_mutex_destroy
actually does nothing except
checking that the mutex is unlocked.
If the mutex is locked by some thread, pthread_mutex_destroy
returns EBUSY
. Otherwise it returns 0.
If any of the above functions (except pthread_mutex_init
)
is applied to an uninitialized mutex, they will simply return
EINVAL
and do nothing.
A shared global variable x can be protected by a mutex as follows:
int x; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
All accesses and modifications to x should be bracketed by calls to
pthread_mutex_lock
and pthread_mutex_unlock
as follows:
pthread_mutex_lock(&mut); /* operate on x */ pthread_mutex_unlock(&mut);
Mutex attributes can be specified at mutex creation time, by passing a
mutex attribute object as second argument to pthread_mutex_init
.
Passing NULL
is equivalent to passing a mutex attribute object
with all attributes set to their default values.
pthread_mutexattr_init
initializes the mutex attribute object
attr and fills it with default values for the attributes.
This function always returns 0.
pthread_mutexattr_destroy
destroys a mutex attribute object,
which must not be reused until it is
reinitialized. pthread_mutexattr_destroy
does nothing in the
LinuxThreads implementation.
This function always returns 0.
LinuxThreads supports only one mutex attribute: the mutex kind, which is
either PTHREAD_MUTEX_FAST_NP
for "fast" mutexes,
PTHREAD_MUTEX_RECURSIVE_NP
for "recursive" mutexes, or
PTHREAD_MUTEX_ERRORCHECK_NP
for "error checking" mutexes. As
the NP
suffix indicates, this is a non-portable extension to the
POSIX standard and should not be employed in portable programs.
The mutex kind determines what happens if a thread attempts to lock a
mutex it already owns with pthread_mutex_lock
. If the mutex is of
the "fast" kind, pthread_mutex_lock
simply suspends the calling
thread forever. If the mutex is of the "error checking" kind,
pthread_mutex_lock
returns immediately with the error code
EDEADLK
. If the mutex is of the "recursive" kind, the call to
pthread_mutex_lock
returns immediately with a success return
code. The number of times the thread owning the mutex has locked it is
recorded in the mutex. The owning thread must call
pthread_mutex_unlock
the same number of times before the mutex
returns to the unlocked state.
The default mutex kind is "fast", that is, PTHREAD_MUTEX_FAST_NP
.
pthread_mutexattr_setkind_np
sets the mutex kind attribute in
attr to the value specified by kind.
If kind is not PTHREAD_MUTEX_FAST_NP
,
PTHREAD_MUTEX_RECURSIVE_NP
, or
PTHREAD_MUTEX_ERRORCHECK_NP
, this function will return
EINVAL
and leave attr unchanged.
pthread_mutexattr_getkind_np
retrieves the current value of the
mutex kind attribute in attr and stores it in the location pointed
to by kind.
This function always returns 0.
Go to the first, previous, next, last section, table of contents.