mirror of
https://github.com/boostorg/thread.git
synced 2026-01-27 19:32:11 +00:00
160 lines
7.7 KiB
HTML
160 lines
7.7 KiB
HTML
<html>
|
|
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<meta name="keywords" content="threads, BTL, thread library, C++">
|
|
<title>Boost.Threads, Mutex Concept</title>
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff" link="#0000ff" vlink="#800080">
|
|
|
|
<table border="0" cellpadding="7" cellspacing="0" width="100%">
|
|
<tr>
|
|
<td valign="top" width="300">
|
|
<h3><IMG height=86 alt="C++ Boost" src="../../../c++boost.gif" width=277></h3>
|
|
</td>
|
|
<td valign="top">
|
|
<h1 align="center">Boost.Threads</h1>
|
|
<h2 align="center">Mutex Concept</h2>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<hr>
|
|
|
|
<p>The purpose of a mutex (short for mutual-exclusion) is to serialize access to
|
|
a resource shared between multiple threads. The mutex concept formalizes this
|
|
idea. A model that implements the mutex concept has two states: locked and
|
|
unlocked. Before using a resource that's shared, a thread would lock the mutex model,
|
|
insuring that it was the only thread accessing the shared resource at a given
|
|
time. When done with the shared resource the thread would unlock the mutex model
|
|
allowing another thread to acquire the lock and use the shared resource.</p>
|
|
|
|
<p>Traditional C thread APIs, such as pthreads or Windows thread APIs, expose methods to
|
|
lock and unlock a mutex model. This is a dangerous way to expose the needed functionality
|
|
since it's easy to forget to unlock a mutex model that's been locked. When the flow of
|
|
control is complex, with multiple return points, the likelihood that you'll forget to
|
|
unlock a mutex model becomes even greater. With exceptions it becomes nearly impossible
|
|
to insure that you unlock the mutex. Many C++ threading libraries have made use of a
|
|
pattern known as <i>Scoped Locking</i><sup><A href="#footnote1">1</A></sup> to help insure
|
|
that a programmer did not forget to unlock the mutex model. With this pattern a
|
|
<A href="lock_concept.html">lock concept</A> is employed where the lock model's constructor
|
|
locks the associated mutex model and the destructor unlocks the mutex model. The
|
|
<b>Boost.Threads</b> library takes this pattern to the extreme, where lock concepts are the
|
|
only way to lock and unlock a mutex model: lock and unlock methods are not exposed by any
|
|
mutex models in <b>Boost.Threads</b>. This helps to insure safe usage patterns, especially
|
|
with regard to code that may throw exceptions.</p>
|
|
|
|
<p>The <b>Boost.Threads</b> library currently defines six mutex models:
|
|
<A href="mutex.html">boost::mutex</A>, <A href="mutex.html">boost::try_mutex</A>,
|
|
<A href="mutex.html">boost::timed_mutex</A>, <A href="recursive_mutex.html">boost::recursive_mutex</A>,
|
|
<A href="recursive_mutex.html">boost::recursive_try_mutex</A> and
|
|
<A href="recursive_mutex.html">boost::recursive_timed_mutex</A>.</p>
|
|
|
|
<h2><a name="LockingStrategies">Locking Strategies</a></h2>
|
|
|
|
<p>Every mutex model follows one of several locking strategies. These strategies
|
|
define the semantics for the locking operation when the calling thread already
|
|
owns a lock on the mutex model.</p>
|
|
|
|
<h3>Recursive</h3>
|
|
|
|
<p>With a recursive locking strategy when a thread attempts to acquire a lock on
|
|
the mutex model for which it already owns a lock the operation returns successfully.
|
|
Internally a lock count is maintained and the owning thread must unlock the
|
|
mutex model the same number of times that it's locked it before the mutex model's
|
|
state returns to unlocked. Since mutex model's in <b>Boost.Threads</b> expose
|
|
locking functionality only through lock concepts it can be proven that a thread
|
|
will always unlock a mutex model the same number of times that it's locked it.
|
|
This helps to eliminate a whole set of errors typically found in traditional
|
|
C style APIs.</p>
|
|
|
|
<p>The <A href="recursive_mutex.html">boost::recursive_mutex</A>,
|
|
<A href="recursive_mutex.html">boost::recursive_try_mutex</A>
|
|
and <A href="recursive_mutex.html">boost::recursive_timed_mutex</A> use this locking strategy.</p>
|
|
|
|
<h3>Checked</h3>
|
|
|
|
<p>With a checked locking strategy when a thread attempts to acquire a lock on
|
|
the mutex model for which it already owns a lock the operation will fail with
|
|
some sort of error indication. Further, attempts by a thread to unlock a mutex
|
|
that was not locked by the thread will also return some sort of error indication.
|
|
In <b>Boost.Threads</b> an exception of type <A href="lock_error.html">boost::lock_error</A>
|
|
is thrown in these cases.</p>
|
|
|
|
<h3>Unchecked</h3>
|
|
|
|
<p>With an unchecked locking strategy when a thread attempts to acquire a lock
|
|
on the mutex model for which it already owns a lock the operation will deadlock. In
|
|
general this locking strategy is less safe than a checked or recursive strategy,
|
|
but it's also a faster strategy and so is employed by many libraries.</p>
|
|
|
|
<p><b>Boost.Threads</b> does not provide a mutex model that explicitly uses this
|
|
strategy.</p>
|
|
|
|
<h3>Unspecified</h3>
|
|
|
|
<p>With an unspecified locking strategy when a thread attempts to acquire a lock
|
|
on a mutex model for which it already owns a lock the operation results in
|
|
<b>undefined behavior</b>. When a mutex model has an unspecified locking strategy the
|
|
programmer must assume that the mutex model instead uses an unchecked strategy.</p>
|
|
|
|
<p>In general a mutex model with an unspecified locking strategy is unsafe, and it
|
|
requires programmer discipline to use the mutex model properly. However, this strategy
|
|
allows an implementation to be as fast as possible with no restrictions on its implementation.
|
|
This is especially true for portable implementations that wrap the native threading support
|
|
of a platform. For this reason the <A href="mutex.html">boost::mutex</A>,
|
|
<A href="mutex.html">boost::try_mutex</A> and <A href="mutex.html">boost::timed_mutex</A> use
|
|
this locking strategy despite the lack of safety.</p>
|
|
|
|
<h2><a name="SchedulingPolicies">Scheduling Policies</a></h2>
|
|
|
|
<p>Every mutex model follows one of several scheduling policies. These policies
|
|
define the semantics for when a mutex model has more than one thread waiting to
|
|
acquire a lock when the mutex model is unlocked. In other words, the policy defines
|
|
which thread shall acquire the lock in this case.</p>
|
|
|
|
<h3>FIFO</h3>
|
|
|
|
<p>With a FIFO scheduling policy threads waiting for the lock will acquire it in
|
|
a first come first serve order (or First In First Out). This can help prevent a
|
|
high priority thread from starving lower priority threads that are also waiting
|
|
on the mutex lock.</p>
|
|
|
|
<h3>Priority Driven</h3>
|
|
|
|
<p>With a Priority Driven scheduling policy the thread with the highest priority
|
|
acquires the lock. Note that this means that low-priority threads may never acquire
|
|
the lock if the mutex model has high contention and there is always at least one high-priority
|
|
thread waiting. This is known as thread starvation. When multiple threads of the same
|
|
priority are waiting on the mutex lock one of the other scheduling priorities will
|
|
determine which thread shall acquire the lock.</p>
|
|
|
|
<h3>Undefined</h3>
|
|
|
|
<p>Threads acquire the lock in no particular order. Users should assume that
|
|
low-priority threads may wait indefinitely, and that threads of the same
|
|
priority acquire the lock in essentially random order.</p>
|
|
|
|
<h3>Unspecified</h3>
|
|
|
|
<p>The mutex model does not specify which scheduling policy is used. The programmer
|
|
must assume that an undefined scheduling policy is used. In order to insure
|
|
portability, all <b>Boost.Threads</b> mutex models use an unspecified scheduling policy.</p>
|
|
|
|
<hr>
|
|
|
|
<h2>Foot Notes</h2>
|
|
|
|
<p><a name="footnote1"><sup>1</sup></a> Douglas Schmidt, Michael Stal, Hans Rohnert, Frank Buschmann:
|
|
<i>Pattern-Oriented Software Architecture - Volume 2 (Patterns for Concurrent
|
|
and Networked Objects)</i>, Wiley, 2000.</p>
|
|
|
|
<hr>
|
|
|
|
<p><i>Copyright <A href="mailto:williamkempf@hotmail.com">William E. Kempf</A>
|
|
2001 all rights reserved.</i></p>
|
|
|
|
</body>
|
|
</html>
|