mirror of
https://github.com/boostorg/thread.git
synced 2026-02-02 09:22:10 +00:00
612 lines
28 KiB
HTML
612 lines
28 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
|
<title>Boost.Threads - RWMutex Concept</title>
|
|
</head>
|
|
<body link="#0000ff" vlink="#800080">
|
|
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
|
"header">
|
|
<tr>
|
|
<td valign="top" width="300">
|
|
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
|
|
</td>
|
|
<td valign="top">
|
|
<h1 align="center">Boost.Threads</h1>
|
|
<h2 align="center">RWMutex Concept</h2>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<hr>
|
|
<dl class="index">
|
|
<dt><a href="#introduction">Introduction</a></dt>
|
|
<dt><a href="#locking-strategies">Locking Strategies</a></dt>
|
|
<dl class="page-index">
|
|
<dt><a href="#locking-strategy-recursive">Recursive</a></dt>
|
|
<dt><a href="#locking-strategy-checked">Checked</a></dt>
|
|
<dt><a href="#locking-strategy-unchecked">Unchecked</a></dt>
|
|
<dt><a href="#locking-strategy-unspecified">Unspecified</a></dt>
|
|
</dl>
|
|
<dt><a href="#scheduling-policies">Scheduling Policies</a></dt>
|
|
<dt><a href="#requirements">Concept Requirements</a></dt>
|
|
<dt><a href="#models">Models</a></dt>
|
|
</dl>
|
|
<h2><a name="introduction"></a>Introduction</h2>
|
|
<p>A rw_mutex (short for reader-writer mutual-exclusion) concept serializes access
|
|
to a resource shared between multiple threads, where multiple readers can share
|
|
simultaneous access, but writers require exclusive access. The <a href="#Mutex">
|
|
RWMutex</a> concept, with <a href="#TryMutex">TryRWMutex</a> and <a href="#TimedMutex">
|
|
TimedRWMutex</a> refinements, formalize the requirements. A model that implements
|
|
RWMutex and its refinements has three states: <b>shared-locked</b> ,<b>exclusive-locked</b>
|
|
and <b>unlocked</b>. Before reading from a shared resource, a thread <b>shared-locks</b>
|
|
a Boost.Threads rw_mutex model object, insuring <a href="definitions.html#Thread-safe">
|
|
thread-safe</a> access for reading from the shared resource. Before writing
|
|
to a shared resource, a thread <b>exclusive-locks</b> a Boost.Threads rw_mutex
|
|
model object, insuring <a href="definitions.html#Thread-safe">thread-safe</a>
|
|
access for altering 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> Some traditional C thread APIs like Pthreads provide implementations for rw_mutex
|
|
(also known as reader-writer locks). Others like Windows thread APIs do
|
|
not provide a rw_mutex primitive. Some of those APIs expose functions
|
|
to lock and unlock a rw_mutex model. This is dangerous since it's easy to forget
|
|
to unlock a locked rw_mutex. When the flow of control is complex, with multiple
|
|
return points, the likelihood of forgetting to unlock a rw_mutex model would
|
|
become even greater. When exceptions are thrown, it becomes nearly impossible
|
|
to ensure that the rw_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 rw_mutexes. With this pattern, a <a href="lock_concept.html">lock concept</a>
|
|
is employed where the lock model's constructor locks the associated rw_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 rw_mutex model: lock and unlock functions are not exposed
|
|
by any <b>Boost.Threads</b> rw_mutex models. This helps to ensure safe usage
|
|
patterns, especially when code throws exceptions.</p>
|
|
<h2><a name="locking-strategies"></a>Locking Strategies</h2>
|
|
<P>Every rw_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 rw_mutex model.</P>
|
|
<h3><a name="locking-strategy-recursive"></a>Recursive</h3>
|
|
<P>With a recursive locking strategy when a thread attempts to acquire an additional lock
|
|
on the rw_mutex model for which it already owns a lock, the operation is successful,
|
|
except possibly in the case where a shared-lock holding thread attempts
|
|
to obtain an exclusive lock. </P>
|
|
<P>
|
|
<TABLE id="Table9" width="100%" border="1">
|
|
<TR>
|
|
<TD width="22%">Lock Type Held</TD>
|
|
<TD width="18%">Lock Request Type</TD>
|
|
<TD width="60%">Action</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Grant the shared lock immediately</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%">
|
|
<P>If this thread is the only holder of the shared-lock, grants the exclusive
|
|
lock immediately. Otherwise throws lock_error() exception.</P>
|
|
</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Grants the (additional) shared lock immediately.</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%"> Grant the exclusive lock immediately</TD>
|
|
</TR>
|
|
</TABLE>
|
|
<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_rw_mutex</A>, <A href="recursive_mutex.html">
|
|
recursive_try_rw_mutex</A> and <A href="recursive_mutex.html">recursive_timed_rw_mutex</A>
|
|
will use this locking strategy. Successful implementation of this locking
|
|
strategy may require thread identification (see below).</P>
|
|
<h3><a name="locking-strategy-checked"></a>Checked</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, except in the case of multiple shared-lock
|
|
acquisition which is a normal operation for ANY RWMutex. 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>
|
|
<B>
|
|
<P>
|
|
<TABLE id="Table10" width="100%" border="1">
|
|
<TR>
|
|
<TD width="22%">Lock Type Held</TD>
|
|
<TD width="18%">Lock Request Type</TD>
|
|
<TD width="60%">Action</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Grant the shared lock immediately</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%">
|
|
<P>Throw lock_error()</P>
|
|
</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Throw lock_error()</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%"> Throw lock_error()</TD>
|
|
</TR>
|
|
</TABLE>
|
|
<p></P>
|
|
</B>
|
|
<P><B> Boost.Threads</b> does not currently provide any rw_mutex models that use
|
|
this strategy. A successful implementation of this locking strategy would
|
|
likely require thread identification.</P>
|
|
<h3><a name="locking-strategy-unchecked"></a>Unchecked</h3>
|
|
<P>With an unchecked locking strategy when a thread attempts to acquire a lock
|
|
on the rw_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 can be a
|
|
faster strategy and so is employed by many libraries.</P>
|
|
<P>
|
|
<TABLE id="Table11" width="100%" border="1">
|
|
<TR>
|
|
<TD width="22%">Lock Type Held</TD>
|
|
<TD width="18%">Lock Request Type</TD>
|
|
<TD width="60%">Action</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Grant the shared lock immediately</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%">
|
|
<P>Deadlock</P>
|
|
</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Deadlock</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%"> Deadlock</TD>
|
|
</TR>
|
|
</TABLE>
|
|
<p></P>
|
|
<P><B>Boost.Threads</B> does not currently provide any mutex models that use this
|
|
strategy. For RWMutexes on platforms that contain natively recursive synchronization
|
|
primitives, implementing a guaranteed-deadlock can actually involve extra work,
|
|
and would likely require thread identification.</P>
|
|
<h3><a name="locking-strategy-unspecified"></a>Unspecified</h3>
|
|
<P>With an unspecified locking strategy, when a thread attempts to acquire a lock
|
|
on a rw_mutex model for which the thread already owns a lock the operation results
|
|
in <B>undefined behavior</B>. When a rw_mutex model has an unspecified locking
|
|
strategy the programmer must assume that the rw_mutex model instead uses an
|
|
unchecked strategy as the worse case, although some platforms may exhibit a
|
|
mix of unchecked and recursive behavior.</P>
|
|
<P>
|
|
<TABLE id="Table12" width="100%" border="1">
|
|
<TR>
|
|
<TD width="22%">Lock Type Held</TD>
|
|
<TD width="18%">Lock Request Type</TD>
|
|
<TD width="60%">Action</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Grant the shared lock immediately</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-lock</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%">
|
|
<P>Undefined, but generally deadlock</P>
|
|
</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Undefined, but generally deadlock</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%"> Undefined, but generally deadlock</TD>
|
|
</TR>
|
|
</TABLE>
|
|
<p></P>
|
|
<P>In general a rw_mutex model with an unspecified locking strategy is unsafe,
|
|
and it requires programmer discipline to use the rw_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="rw_mutex.html">rw_mutex</A>, <A href="rw_mutex.html">try_rw_mutex</A>
|
|
and <A href="rw_mutex.html">timed_rw_mutex</A> use this locking strategy despite
|
|
the lack of safety.</P>
|
|
<h3>An Aside - Thread Identification</h3>
|
|
<P>RWMutexes can support specific Locking Strategies (recursive and checked) which
|
|
help to detect and protect against self-deadlock. Self-deadlock can occur
|
|
when a holder of a locked RWMutex attempts to obtain another lock. Given
|
|
an implemention "I" which is susceptible to self-deadlock but otherwise correct
|
|
and efficient, a recursive or checked implementation "Ir" or "Ic" can use the
|
|
same basic implementation, but make special checks against self-deadlock by
|
|
tracking the identities of thread(s) currently holding locks. This approach
|
|
makes deadlock detection othrogonal to the basic RWMutex implementaion.
|
|
</P>
|
|
<P> Alternatively, a different basic implementation for RWMutex concepts ,
|
|
I' (I-Prime) may exist which uses recursive or checked versions of synchronization
|
|
primitives to produce a recursive or checked RWMutex while still providing flexibility
|
|
in terms of Scheduling Policies.
|
|
<P>Please refer to the <b>Boost.Threads</b> <a href="mutex_concept.html#LockingStrategies">
|
|
mutex concept</a> documentation for a discussion of locking strategies.
|
|
The rw_mutex supports both the <a href="mutex_concept.html#Recursive"> recursive</a>
|
|
and <a href="mutex_concept.html#Unspecified">unspecified</a> locking strategies.
|
|
RWMutexes are parameterized on a Mutex type which they use to control exclusive-locking
|
|
and access to internal state.
|
|
<H3>Another Aside - <A name="LockingPromotion">Lock Promotion</A></H3>
|
|
<P>RWMutexes can support lock promotion, where a mutex which is in the shared-locked
|
|
state transitions to an exclusive-locked state without releasing the lock.
|
|
If this functionality is supported at all by Boost.Threads, it will only be
|
|
through an explicit promote() operations. Extra care must be taken to
|
|
ensure that only one thread holding a shared lock can block awaiting promotion
|
|
at any given time. If more than one shared-lock holder is allowed
|
|
to enter a blocked state while waiting to be promoted, deadlock will result
|
|
since both threads will be waiting for the other to release their shared lock.
|
|
<h2><a name="scheduling-policies"></a>Scheduling Policies</h2>
|
|
<p>Every rw_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. For rw_mutex, it is particularly
|
|
important to define the behavior when threads are requesting both shared and
|
|
exclusive access simultaneously. This will be referred to as "inter-class
|
|
scheduling". </p>
|
|
<p>For some types of inter-class scheduling, an intra-class scheduling policy
|
|
can also be defined that will describe the order in which waiting threads of
|
|
the same class will acquire the thread.</p>
|
|
<h3><a name="ReaderPriority">ReaderPriority</a></h3>
|
|
<p>With ReaderPriority, any pending request for a shared lock will have priority
|
|
over a pending request for an exclusive lock, irrespective of the current lock
|
|
state of the rw_mutex, and irrespective of the relative order that the pending
|
|
requests arrive.</p>
|
|
<table border="1" width="100%" id="Table1">
|
|
<tr>
|
|
<td width="22%">Current rw_mutex state</td>
|
|
<td width="18%">Request Type</td>
|
|
<td width="60%">Action</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">unlocked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%">Grant the shared lock immediately</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">shared-locked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%">Grant the additional shared lock immediately.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">exclusive-locked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%">Wait to acquire the lock until the thread holding the exclusive-lock
|
|
releases its lock. A shared lock will be granted to all pending readers
|
|
before any other thread can acquire an exclusive lock.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">unlocked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">Grant the exclusive lock immediately, if and only if there
|
|
are no pending shared-lock requests.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">shared-locked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%"> Wait to acquire the lock until all threads holding shared
|
|
locks release their locks -AND- no requests for shared locks exist.
|
|
If other exclusive-lock requests exist, the lock is granted in accordance
|
|
with the intra-request scheduling policy.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">exclusive-locked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">Wait to acquire the lock until the thread holding the exclusive
|
|
lock releases its lock -AND- no requests for shared locks exist. If
|
|
other exclusive-lock requests exist, the lock is granted in accordance with
|
|
the intra-request scheduling policy.</td>
|
|
</tr>
|
|
</table>
|
|
<h3><a name="WriterPriority">WriterPriority</a></h3>
|
|
<p>With WriterPriority, any pending request for an exclusive lock will have priority
|
|
over a pending request for a shared lock, irrespective of the current lock state
|
|
of the rw_mutex, and irrespective of the relative order that the pending requests
|
|
arrive.</p>
|
|
<table border="1" width="100%" id="Table2">
|
|
<tr>
|
|
<td width="22%">Current rw_mutex state</td>
|
|
<td width="18%">Request Type</td>
|
|
<td width="60%">Action</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">unlocked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%">Grant the shared lock immediately.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">shared-locked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%">Grant the additional shared lock immediately, -IF- no outstanding
|
|
requests for an exclusive lock exist.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">exclusive-locked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%"> Wait to acquire the lock until the thread holding the exclusive-lock
|
|
releases its lock. The shared lock will be granted once no other
|
|
outstanding exclusive-lock requests exist.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">unlocked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">Grant the exclusive lock immediately.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">shared-locked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">Wait to acquire the lock until all threads holding shared
|
|
locks release their locks. If other exclusive-lock requests exist,
|
|
the lock is granted in accordance with the intra-request scheduling policy.
|
|
This request will be granted before any new shared-lock requests are granted.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">exclusive-locked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">Wait to acquire the lock until the thread holding the exclusive
|
|
lock releases its lock. If other exclusive-lock requests exist, the
|
|
lock is granted in accordance with the intra-request scheduling policy.
|
|
This request will be granted before any new shared-lock requests are granted.</td>
|
|
</tr>
|
|
</table>
|
|
<h3><a name="AlteratingManyPriority">AlternatingPriority</a>/ManyReads</h3>
|
|
<p>With AlternatingPriority/ManyReads, reader or writer starvation is avoided
|
|
by alternatively granting shared or exclusive access when pending requests exist
|
|
for both types of locks. Outstanding shared-lock requests are treated
|
|
as a group when it is the "reader's turn"</p>
|
|
<table border="1" width="100%" id="Table3">
|
|
<tr>
|
|
<td width="22%">Current rw_mutex state</td>
|
|
<td width="18%">Request Type</td>
|
|
<td width="60%">Action</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">unlocked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%">Grant the shared lock immediately.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">shared-locked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%">Grant the additional shared lock immediately, -IF- no outstanding
|
|
requests for an exclusive lock exist. If outstanding exclusive-lock
|
|
requests exist, this lock will not be granted until at least one of the
|
|
exclusive locks is granted and released. If other shared-lock requests exist,
|
|
all shared-locks will be granted as a group.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">exclusive-locked</td>
|
|
<td width="18%">shared-lock</td>
|
|
<td width="60%"> Wait to acquire the lock until the thread holding the exclusive-lock
|
|
releases its lock. If other outstanding exclusive-lock requests exist,
|
|
they will have to wait until all current shared-lock requests are serviced.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">unlocked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">Grant the exclusive lock immediately.</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">shared-locked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">
|
|
<P>Wait to acquire the lock until all threads holding shared locks release
|
|
their locks. </P>
|
|
<P>If other exclusive-lock requests exist, this lock will be granted
|
|
to one of them in accordance with the intra-request scheduling policy.</P>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="22%">exclusive-locked</td>
|
|
<td width="18%">exclusive-lock</td>
|
|
<td width="60%">Wait to acquire the lock until the thread holding the exclusive
|
|
lock releases its lock. If other outstanding shared-lock requests
|
|
exist, this lock will not be granted until all of the currently waiting
|
|
shared locks are granted and released. If other exclusive-lock
|
|
requests exist, this lock will be granted in accordance with the intra-request
|
|
scheduling policy.</td>
|
|
</tr>
|
|
</table>
|
|
<H3>
|
|
<H3><A name="AlteratingSinglePriority">AlternatingPriority</A>/SingleReads</H3>
|
|
</H3>
|
|
<P>With AlternatingPriority/ManyReads, reader or writer starvation is avoided
|
|
by alternatively granting shared or exclusive access when pending requests exist
|
|
for both types of locks. Outstanding shared-lock requests are services
|
|
one at a time when it is the "reader's turn"</P>
|
|
<H3>
|
|
<TABLE id="Table13" width="100%" border="1">
|
|
<TR>
|
|
<TD width="22%">Current rw_mutex state</TD>
|
|
<TD width="18%">Request Type</TD>
|
|
<TD width="60%">Action</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">unlocked</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Grant the shared lock immediately.</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-locked</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">Grant the additional shared lock immediately, -IF- no outstanding
|
|
requests for an exclusive lock exist. If outstanding exclusive-lock
|
|
requests exist, this lock will not be granted until at least one of the
|
|
exclusive locks is granted and released. </TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">shared-lock</TD>
|
|
<TD width="60%">
|
|
<P>Wait to acquire the lock until the thread holding the exclusive-lock
|
|
releases its lock.</P>
|
|
<P>If other outstanding exclusive-lock requests exist, exactly one shared-lock
|
|
request will be granted before the next exclusive lock is granted.</P>
|
|
</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">unlocked</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%">Grant the exclusive lock immediately.</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">shared-locked</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%">
|
|
<P>Wait to acquire the lock until all threads holding shared locks release
|
|
their locks. </P>
|
|
<P>If other exclusive-lock requests exist, this lock will be granted
|
|
to one of them in accordance with the intra-request scheduling policy.</P>
|
|
</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD width="22%">exclusive-locked</TD>
|
|
<TD width="18%">exclusive-lock</TD>
|
|
<TD width="60%">Wait to acquire the lock until the thread holding the exclusive
|
|
lock releases its lock. If other outstanding shared-lock requests
|
|
exist, this lock can not be granted until exactly one shared-lock request
|
|
is granted and released. If other exclusive-lock requests exist,
|
|
this lock will be granted in accordance with the intra-request scheduling
|
|
policy.</TD>
|
|
</TR>
|
|
</TABLE>
|
|
</H3>
|
|
<h3>Intra-Request Scheduling Policy</h3>
|
|
<p>Please refer to the <b>Boost.Threads</b> <a href="mutex_concept.html#SchedulingPolicies">
|
|
mutex concept</a> documentation for a discussion of mutex scheduling policies,
|
|
which are identical to RWMutex Intra-Request scheduling policies. The
|
|
rw_mutex supports only the <a href="mutex_concept.html#UnspecifiedScheduling">
|
|
Unspecified</a> intra-request scheduling policy. That is, given a set
|
|
of threads waiting for exclusive locks, the order (amongst themselves) in which
|
|
they receive the lock is unspecified.</p>
|
|
<h2><a name="requirements"></a>Concept Requirements</h2>
|
|
<h3>RW<a name="Mutex">Mutex</a> Concept</h3>
|
|
<p>A RWMutex object has three states: shared-locked, exclusive-locked, and unlocked.
|
|
RWMutex object state can only be determined by an object meeting the <a href="rw_lock_concept.html#ScopedLock">
|
|
ScopedRWLock</a> requirements and constructed for the RWMutex object.</p>
|
|
<p>A RWMutex is <a href="../../utility/utility.htm#Class noncopyable">noncopyable</a>.</p>
|
|
<p> For a RWMutex type RWM, 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" id="Table5">
|
|
<tr>
|
|
<td><b>Expression</b></td>
|
|
<td><b>Effects</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>RWM m;</code></td>
|
|
<td>Constructs a rw_mutex object m. Post-condition: m is unlocked.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>(&m)->~RWM();</code></td>
|
|
<td>Precondition: m is unlocked. Destroys a rw_mutex object m.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>RWM::scoped_rw_lock</code></td>
|
|
<td>A type meeting the <a href="rw_lock_concept.html#ScopedRWLock">ScopedRWLock</a>
|
|
requirements. </td>
|
|
</tr>
|
|
</table>
|
|
<h3><a name="TryMutex">TryRWMutex</a> Concept</h3>
|
|
<p>A TryRWMutex must meet the <a href="#RWMutex">RWMutex</a> requirements. In
|
|
addition, for a TryRWMutex type RWM 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" id="Table6">
|
|
<tr>
|
|
<td><b>Expression</b></td>
|
|
<td><b>Effects</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>RWM::scoped_try_rw_lock</code></td>
|
|
<td>A type meeting the <a href="rw_lock_concept.html#ScopedTryRWLock">ScopedTryRWLock</a>
|
|
requirements.</td>
|
|
</tr>
|
|
</table>
|
|
<h3><a name="TimedMutex">TimedRWMutex</a> Concept</h3>
|
|
<p>A TimedRWMutex must meet the <a href="#TryMutex">TryRWMutex</a> requirements.
|
|
In addition, for a TimedRWMutex type RWM 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" id="Table7">
|
|
<tr>
|
|
<td><b>Expression</b></td>
|
|
<td><b>Effects</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>RWM::scoped_timed_rw_lock</code></td>
|
|
<td>A type meeting the <a href="rw_lock_concept.html#ScopedTimedRWLock">ScopedTimedRWLock</a>
|
|
requirements.</td>
|
|
</tr>
|
|
</table>
|
|
<h2><a name="models"></a>Models</h2>
|
|
<p><b>Boost.Threads</b> currently supplies three classes which model rw_mutex
|
|
concepts.</p>
|
|
<table summary="Mutex concept classes" border="1" cellpadding="5" id="Table8">
|
|
<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">RWMutex</a></td>
|
|
<td valign="top"> </td>
|
|
<td><a href="rw_mutex.html">rw_mutex<Mutex></a></td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top"><a href="#TryMutex">TryRWMutex</a></td>
|
|
<td valign="top"><a href="#Mutex">RWMutex</a></td>
|
|
<td><a href="rw_mutex.html">try_rw_mutex<TryMutex> </a> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top"><a href="#TimedMutex">TimedRWMutex</a></td>
|
|
<td valign="top"><a href="#TryMutex">TryRWMutex</a></td>
|
|
<td><a href="rw_mutex.html">timed_rw_mutex<TimedMutex> </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:{{address}}">{{author}}</a> 2002. All Rights
|
|
Reserved.</i></p>
|
|
</body>
|
|
</html>
|