mirror of
https://github.com/boostorg/thread.git
synced 2026-01-22 17:52:18 +00:00
338 lines
15 KiB
HTML
338 lines
15 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 summary="header" 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 Concepts</h2>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<hr>
|
|
|
|
<p><a href="#Introduction">Introduction</a><br>
|
|
<a href="#LockingStrategies">Locking Strategies</a><br>
|
|
<a href="#Recursive">Recursive</a><br>
|
|
<a href="#CheckedStrategy">Checked</a><br>
|
|
<a href="#UncheckedStrategy">Unchecked</a><br>
|
|
<a href="#UnspecifiedStrategy">
|
|
Unspecified</a><br>
|
|
<a href="#SchedulingPolicies">Scheduling Policies</a><br>
|
|
<a href="#FIFO">FIFO</a><br>
|
|
<a href="#Priority Driven">Priority
|
|
Driven</a><br>
|
|
<a href="#UndefinedScheduling">
|
|
Undefined</a><br>
|
|
<a href="#UnspecifiedScheduling">
|
|
Unspecified</a><br>
|
|
<a href="#Requirements">Concept Requirements</a><br>
|
|
<a href="#Mutex">Mutex Concept</a><br>
|
|
<a href="#TryMutex">TryMutex Concept</a><br>
|
|
<a href="#TimedMutex">TimedMutex
|
|
Concept</a><br>
|
|
<a href="#Models">Models</a></p>
|
|
|
|
<h2><a name="Introduction">Introduction</a></h2>
|
|
|
|
<p>A mutex (short for mutual-exclusion) concept serializes access to a
|
|
resource shared between multiple threads. The <a href="#Mutex">
|
|
Mutex</a> concept, with <a href="#TryMutex">TryMutex</a> and <a href=
|
|
"#TimedMutex">TimedMutex</a> refinements, formalize the requirements. A
|
|
model that implements Mutex and its refinements has two states: <b>
|
|
locked</b> and <b>unlocked</b>. Before using a shared resource, a
|
|
thread locks a Boost.Threads mutex model object, insuring <a href=
|
|
"definitions.html#Thread-safe">thread-safe</a> access to the shared
|
|
resource. When use of the shared resource is complete, the thread
|
|
unlocks the mutex model object, allowing another thread to acquire the
|
|
lock and use the shared resource.</p>
|
|
|
|
<p>Traditional C thread APIs, like Pthreads or the Windows thread APIs,
|
|
expose functions to lock and unlock a mutex model. This is dangerous
|
|
since it's easy to forget to unlock a locked mutex. When the flow
|
|
of control is complex, with multiple return points, the likelihood of
|
|
forgetting to unlock a mutex model would become even greater. When
|
|
exceptions are thrown, it becomes nearly impossible to ensure that the
|
|
mutex is unlocked properly when using these traditional API's. The
|
|
result is <a href="definitions.html#Deadlock">deadlock</a>.</p>
|
|
|
|
<p>Many C++ threading libraries use a pattern known as <i>Scoped
|
|
Locking</i> <a href="bibliography.html#Schmidt 00">[Schmidt 00]</a> to
|
|
free the programmer from the need to explicitly lock and unlock
|
|
mutexes. 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 automatically does the
|
|
unlocking. The <b>Boost.Threads</b> library takes this pattern to the
|
|
extreme in that lock concepts are the only way to lock and unlock a
|
|
mutex model: lock and unlock functions are not exposed by any <b>
|
|
Boost.Threads</b> mutex models. This helps to ensure safe usage
|
|
patterns, especially when code throws exceptions.</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><a name="Recursive">Recursive</a></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 is successful. Note the distinction between a thread, which
|
|
may have multiple locks outstanding on a recursive mutex, and a lock
|
|
object, which even for a recursive mutex cannot have its lock()
|
|
function called multiple times without first calling unlock().</p>
|
|
|
|
<p>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
|
|
models in <b>Boost.Threads</b> expose locking functionality only
|
|
through lock concepts, a thread will always unlock a mutex model the
|
|
same number of times that it locked it. This helps to eliminate a whole
|
|
set of errors typically found in traditional C style thread APIs.</p>
|
|
|
|
<p>Classes <a href="recursive_mutex.html">recursive_mutex</a>, <a href=
|
|
"recursive_mutex.html">recursive_try_mutex</a> and <a href=
|
|
"recursive_mutex.html">recursive_timed_mutex</a> use this locking
|
|
strategy.</p>
|
|
|
|
<h3><a name="CheckedStrategy">Checked</a></h3>
|
|
|
|
<p>With a checked locking strategy when a thread attempts to acquire a
|
|
lock on the mutex model for which the thread 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">
|
|
lock_error</a> would be thrown in these cases.</p>
|
|
|
|
<p><b>Boost.Threads</b> does not currently provide any mutex models
|
|
that use this strategy.</p>
|
|
|
|
<h3><a name="UncheckedStrategy">Unchecked</a></h3>
|
|
|
|
<p>With an unchecked locking strategy when a thread attempts to acquire
|
|
a lock on the mutex model for which the thread already owns a lock the
|
|
operation will <a href="definitions.html#Deadlock">deadlock</a>. 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 currently provide any mutex models
|
|
that use this strategy.</p>
|
|
|
|
<h3><a name="UnspecifiedStrategy">Unspecified</a></h3>
|
|
|
|
<p>With an unspecified locking strategy, when a thread attempts to
|
|
acquire a lock on a mutex model for which the thread 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 classes <a href=
|
|
"mutex.html">mutex</a>, <a href="mutex.html">try_mutex</a> and <a href=
|
|
"mutex.html">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 when the mutex model is unlocked and
|
|
there is more than one thread waiting to acquire a lock. In other
|
|
words, the policy defines which waiting thread shall acquire the
|
|
lock.</p>
|
|
|
|
<h3><a name="FIFO">FIFO</a></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><a name="Priority Driven">Priority Driven</a></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><a name="UndefinedScheduling">Undefined</a></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><a name="UnspecifiedScheduling">Unspecified</a></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 ensure portability, all <b>Boost.Threads</b> mutex models
|
|
use an unspecified scheduling policy.</p>
|
|
|
|
<h2>Concept <a name="Requirements">Requirements</a></h2>
|
|
|
|
<h3><a name="Mutex">Mutex</a> Concept</h3>
|
|
|
|
<p>A Mutex object has two states: locked and unlocked. Mutex object
|
|
state can only be determined by an object meeting the <a href=
|
|
"lock_concept.html#ScopedLock">ScopedLock</a> requirements and
|
|
constructed for the Mutex object.</p>
|
|
|
|
<p>A Mutex is <a href="../../utility/utility.htm#Class noncopyable">
|
|
noncopyable</a>.</p>
|
|
|
|
<p>For a Mutex type M and an object m of that type, the following
|
|
expressions must be well-formed and have the indicated effects.</p>
|
|
|
|
<table summary="Mutex expressions" border="1" cellpadding="5">
|
|
<tr>
|
|
<td><b>Expression</b></td>
|
|
|
|
<td><b>Effects</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>M m;</code></td>
|
|
|
|
<td>Constructs a mutex object m. Post-condition: m is
|
|
unlocked.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>(&m)->~M();</code></td>
|
|
|
|
<td>Precondition: m is unlocked. Destroys a mutex object
|
|
m.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>M::scoped_lock</code></td>
|
|
|
|
<td>A type meeting the <a href="lock_concept.html#ScopedLock">
|
|
ScopedLock</a> requirements.</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h3><a name="TryMutex">TryMutex</a> Concept</h3>
|
|
|
|
<p>A TryMutex must meet the <a href="#Mutex">Mutex</a> requirements. In
|
|
addition, for a TryMutex type M and an object m of that type, the
|
|
following expressions must be well-formed and have the indicated
|
|
effects.</p>
|
|
|
|
<table summary="TryMutex expressions" border="1" cellpadding="5">
|
|
<tr>
|
|
<td><b>Expression</b></td>
|
|
|
|
<td><b>Effects</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>M::scoped_try_lock</code></td>
|
|
|
|
<td>A type meeting the <a href=
|
|
"lock_concept.html#ScopedTryLock">ScopedTryLock</a>
|
|
requirements.</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h3><a name="TimedMutex">TimedMutex</a> Concept</h3>
|
|
|
|
<p>A TimedMutex must meet the <a href="#TryMutex">TryMutex</a>
|
|
requirements. In addition, for a TimedMutex type M and an object m of
|
|
that type, the following expressions must be well-formed and have the
|
|
indicated effects.</p>
|
|
|
|
<table summary="TimedMutex expressions" border="1" cellpadding="5">
|
|
<tr>
|
|
<td><b>Expression</b></td>
|
|
|
|
<td><b>Effects</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>M::scoped_timed_lock</code></td>
|
|
|
|
<td>A type meeting the <a href=
|
|
"lock_concept.html#ScopedTimedLock">ScopedTimedLock</a>
|
|
requirements.</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h2><a name="Models">Models</a></h2>
|
|
|
|
<p><b>Boost.Threads</b> currently supplies six classes which model
|
|
mutex concepts.</p>
|
|
|
|
<table summary="Mutex concept classes" border="1" cellpadding="5">
|
|
<tr>
|
|
<td><b>Concept</b></td>
|
|
|
|
<td><b>Refines</b></td>
|
|
|
|
<td><b>Classes Modeling the Concept</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td valign="top"><a href="#Mutex">Mutex</a></td>
|
|
|
|
<td valign="top"> </td>
|
|
|
|
<td><a href="mutex.html">mutex</a><br>
|
|
<a href="recursive_mutex.html">recursive_mutex</a></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td valign="top"><a href="#TryMutex">TryMutex</a></td>
|
|
|
|
<td valign="top"><a href="#Mutex">Mutex</a></td>
|
|
|
|
<td><a href="mutex.html">try_mutex<br>
|
|
</a> <a href="recursive_mutex.html">recursive_try_mutex</a>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td valign="top"><a href="#TimedMutex">TimedMutex</a></td>
|
|
|
|
<td valign="top"><a href="#TryMutex">TryMutex</a></td>
|
|
|
|
<td><a href="mutex.html">timed_mutex<br>
|
|
</a> <a href="recursive_mutex.html">
|
|
recursive_timed_mutex</a></td>
|
|
</tr>
|
|
</table>
|
|
<hr>
|
|
|
|
<p>Revised
|
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->05 November, 2001<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
|
|
|
|
<p><i>© Copyright <a href="mailto:williamkempf@hotmail.com">
|
|
William E. Kempf</a> 2001 all rights reserved.</i></p>
|
|
</body>
|
|
</html>
|
|
|