2
0
mirror of https://github.com/boostorg/thread.git synced 2026-01-23 18:12:12 +00:00
Files
thread/doc/rw_mutex.html
William E. Kempf 07ecf15f4c Added rw_mutex
[SVN r13593]
2002-04-30 19:10:14 +00:00

354 lines
14 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 - Header &lt;boost/thread/rw_mutex.hpp&gt;</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">Header &lt;<a href="../../../boost/thread/rw_mutex.hpp">boost/thread/rw_mutex.hpp</a>&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#macros">Macros</a></dt>
<dl class="page-index">
<dt><a href="#macro-spec">{{macro name}}</a></dt>
</dl>
<dt><a href="#values">Values</a></dt>
<dl class="page-index">
<dt><a href="#value-spec">{{value name}}</a></dt>
</dl>
<dt><a href="#types">Types</a></dt>
<dl class="page-index">
<dt><a href="#type-spec">{{type name}}</a></dt>
</dl>
<dt><a href="#classes">Classes</a></dt>
<dl class="page-index">
<dt><a href="#class-spec">Class <code>{{class name}}</code></a></dt>
<dl class="page-index">
<dt><a href="#class-spec-synopsis">Class <code>{{class name}}</code> synopsis</a></dt>
<dt><a href="#class-spec-ctors">Class <code>{{class name}}</code> constructors
and destructor</a></dt>
<dt><a href="#class-spec-comparisons">Class <code>{{class name}}</code>
comparison functions</a></dt>
<dt><a href="#class-spec-modifiers">Class <code>{{class name}}</code> modifier
functions</a></dt>
<dt><a href="#class-spec-observers">Class <code>{{class name}}</code> observer
functions</a></dt>
<dt><a href="#class-spec-statics">Class <code>{{class name}}</code> static
functions</a></dt>
</dl>
</dl>
<dt><a href="#functions">Functions</a></dt>
<dl class="page-index">
<dt><a href="#function-spec">{{function name}}</a></dt>
</dl>
<dt><a href="#objects">Objects</a></dt>
<dl class="page-index">
<dt><a href="#object-spec">{{object name}}</a></dt>
</dl>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>The <tt><a href="#rw_mutex Synopsis">rw_mutex</a></tt>, <tt><a href="#try_rw_mutex Synopsis">
try_rw_mutex</a></tt> and <tt><a href="#timed_rw_mutex Synopsis">timed_rw_mutex</a></tt>
classes define full featured models of the <a href="rw_mutex_concept.html#rw_mutex">
RWMutex</a>, <a href="rw_mutex_concept.html#TryMutex">TryRWMutex</a>, and <a href="rw_mutex_concept.html#TimedMutex">
TimedRWMutex</a> concepts. These types should be used to synchronize access
to shared resources.&nbsp; Recursive or non-recursive locking mechanics are
acheived by supplying the appropriate Mutex type as a parameter.</p>
<p>Each class supplies one or more typedefs for lock types which model matching
lock concepts. For the best possible performance you should use the rw_mutex
class that supports the minimum set of lock types that you need.</p>
<table summary="lock types" border="1" cellpadding="5">
<tr>
<td><b>rw_mutex Class</b></td>
<td><b>Lock name</b></td>
<td><b>Implementation defined Lock Type</b></td>
<td><b>Lock Concept</b></td>
</tr>
<tr>
<td valign="top"><a href="#rw_mutex Synopsis"><code> rw_mutex</code></a></td>
<td valign="center"><code> scoped_rw_lock</code></td>
<td valign="center"><code><a href="scoped_lock.html">boost::</a></code><a href="scoped_lock.html"><code>detail::thread::scoped_rw_lock&lt;rw_mutex&gt;</code></a></td>
<td valign="center">ScopedRWLock</td>
</tr>
<tr>
<td valign="top"><tt><a href="#try_rw_mutex Synopsis"> try_rw_mutex</a></tt>
</td>
<td valign="center"><code> scoped_rw_lock<br>
scoped_try_rw_lock</code></td>
<td valign="center"><code><a href="scoped_lock.html">boost::</a></code><a href="scoped_lock.html"><code>detail::thread::scoped_rw_lock&lt;try_rw_mutex&gt;</code></a>
<code><a href="scoped_try_lock.html"> <br>
</a><a href="scoped_lock.html">boost::</a></code><a href="scoped_lock.html"><code>detail::thread::scoped_try_rw_lock&lt;try_rw_mutex&gt;</code></a></td>
<td valign="center">ScopedRWLock<br>
ScopedRWTryLock</td>
</tr>
<tr>
<td valign="top"><code><a href="#timed_rw_mutex Synopsis"> timed_rw_mutex</a></code>
</td>
<td valign="center"><code> scoped_rw_lock<br>
scoped_try_rw_lock<br>
scoped_timed_rw_lock</code></td>
<td valign="center"><code><a href="scoped_lock.html">boost::</a></code><a href="scoped_lock.html"><code>detail::thread::scoped_rw_lock&lt;timed_rw_mutex&gt;</code></a>
<code><a href="scoped_try_lock.html"> <br>
</a><a href="scoped_lock.html">boost::</a></code><a href="scoped_lock.html"><code>detail::thread::scoped_try_rw_lock&lt;timed_rw_mutex&gt;</code></a><a href="scoped_timed_lock.html"><code><br>
</code></a><code><a href="scoped_lock.html">boost::</a></code><a href="scoped_lock.html"><code>detail::thread::scoped_timed_rw_lock&lt;timed_rw_mutex&gt;</code></a></td>
<td valign="center">ScopedRWLock<br>
ScopedRWTryLock<br>
ScopedRWTimedLock</td>
</tr>
</table>
<p>The <tt>rw_mutex</tt>, <tt>try_rw_mutex</tt> and <tt>timed_rw_mutex</tt> classes
leave the locking strategy as Unspecified.&nbsp; Programmers should assume that
threads that lock a rw_mutex, try_rw_mutex, or timed_rw_mutex multiple times
will deadlock, unless all of the lock requests are for read-locks.&nbsp;&nbsp;</p>
<p>The <tt>rw_mutex</tt>, <tt>try_rw_mutex</tt> and <tt>timed_rw_mutex</tt> allow
the programmer to explicitly choose&nbsp;the <a href="rw_mutex_concept.html#SchedulingPolicies">
scheduling policy</a> for the lock.&nbsp; This scheduling policy will dictate
how competing readers and writers will acquire the lock.&nbsp; It does not,
however, dictate the order that individual read or write requests will be granted,
in comparison to other requests of the same type.&nbsp;&nbsp;Programmers should
assume that threads waiting for a lock on objects of these types acquire the
lock in a random order, even though the specific behavior for a given platform
may be different.</p>
<H2>Release Notes/Caveats</H2>
<UL>
<LI> Self-deadlock is virtually guaranteed if a thread tries to lock the same
rw_mutex multiple times, unless all locks are read-locks (but see below)</LI>
<LI> This implementation does not protect against reader overflow.&nbsp; If
more than INT_MAX readers obtain or try to obtain a lock simultaneously, the
behavior is undefined.&nbsp; This will be addressed in a future release, but
it seems that detecting this condition &amp; reporting an error or throwing
an exception should suffice for realistic uses.&nbsp; Having readers beyond
INT_MAX wait for the count to decrease only pushes the overflow problem onto
another variable...&nbsp; Suggestions?</LI>
<LI> See the comments at the head of rw_mutex.cpp for a description of the implementation
itself.</LI>
</UL>
<h2><a name="macros"></a>Macros</h2>
<p><a name="macro-spec"></a>{{Macro specifications}}</p>
<h2><a name="values"></a>Values</h2>
<pre>
namespace boost {
typedef enum
{
sp_writer_priority,
sp_reader_priority,
sp_alternating_many_reads,
sp_alternating_single_reads
} rw_scheduling_policy;
typedef enum
{
NO_LOCK,
SHARED_LOCK,
EXCL_LOCK
} lockstate;
}
</pre>
<h2><a name="types"></a>Types</h2>
<p><a name="type-spec"></a>{{Type specifications}}</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class-rw_mutex"></a>Class <code>rw_mutex</code></h3>
<p>{{text}}</p>
<h4><a name="class-rw_mutex-synopsis"></a>Class <code>rw_mutex</code> synopsis</h4>
<pre>
namespace boost
{
class rw_mutex : private <a href="../../utility/utility.htm">boost::noncopyable</a> // Exposition only.
// Class mutex meets the <a href="overview.html#non-copyable">NonCopyable</a> requirement.
{
public:
typedef <i>[implementation defined; see <a href="#introduction">Introduction</a>]</i> scoped_rw_lock;
rw_mutex(rw_scheduling_policy sp=sp_writer_priority);
~rw_mutex();
};
};
</pre>
<h4><a name="class-rw_mutex-ctors"></a>Class <code>rw_mutex</code> constructors
and destructor</h4>
<pre>
rw_mutex(rw_scheduling_policy sp=sp_writer_priority);
</pre>
<dl class="function-semantics">
<dt><b>Postconditions:</b> <code>*this</code> is in the NO_LOCK state.</dt>
</dl>
<pre>
~rw_mutex();
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>*this</code> is in the NO_LOCK state.</dt>
<dt><b>Effects:</b> Destroys <code>*this</code>.</dt>
<dt><b>Danger:</b> Destruction of a locked rw_mutex is a serious programming
error resulting in undefined behavior such as a program crash.</dt>
</dl>
<h3><a name="class-rw_try_mutex"></a>Class <code>rw_try_mutex</code></h3>
<p>{{text}}</p>
<h4><a name="class-rw_try_mutex-synopsis"></a>Class <code>rw_try_mutex</code>
synopsis</h4>
<pre>
namespace boost
{
class rw_mutex : private <a href="../../utility/utility.htm">boost::noncopyable</a> // Exposition only.
// Class mutex meets the <a href="overview.html#non-copyable">NonCopyable</a> requirement.
{
public:
typedef <i>[implementation defined; see <a href="#introduction">Introduction</a>]</i> scoped_rw_lock;
typedef <i>[implementation defined; see <a href="#introduction">Introduction</a>]</i> scoped_rw_try_lock;
rw_try_mutex(rw_scheduling_policy sp=sp_writer_priority);
~rw_try_mutex();
};
};
</pre>
<h4><a name="class-rw_try_mutex-ctors"></a>Class <code>rw_try_mutex</code> constructors
and destructor</h4>
<pre>
rw_try_mutex(rw_scheduling_policy sp=sp_writer_priority);
</pre>
<dl class="function-semantics">
<dt><b>Postconditions:</b> <code>*this</code> is in the NO_LOCK state.</dt>
</dl>
<pre>
~rw_try_mutex();
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>*this</code> is in the NO_LOCK state.</dt>
<dt><b>Effects:</b> Destroys <code>*this</code>.</dt>
<dt><b>Danger:</b> Destruction of a locked rw_mutex is a serious programming
error resulting in undefined behavior such as a program crash.</dt>
</dl>
<h3><a name="class-rw_timed_mutex"></a>Class <code>rw_timed_mutex</code></h3>
<p>{{text}}</p>
<h4><a name="class-rw_timed_mutex-synopsis"></a>Class <code>rw_timed_mutex</code>
synopsis</h4>
<pre>
namespace boost
{
class rw_timed_mutex : private <a href="../../utility/utility.htm">boost::noncopyable</a> // Exposition only.
// Class mutex meets the <a href="overview.html#non-copyable">NonCopyable</a> requirement.
{
public:
typedef <i>[implementation defined; see <a href="#introduction">Introduction</a>]</i> scoped_rw_lock;
typedef <i>[implementation defined; see <a href="#introduction">Introduction</a>]</i> scoped_rw_try_lock;
typedef <i>[implementation defined; see <a href="#introduction">Introduction</a>]</i> scoped_rw_timed_lock;
rw_timed_mutex(rw_scheduling_policy sp=sp_writer_priority);
~rw_timed_mutex();
};
};
</pre>
<h4><a name="class-rw_timed_mutex-ctors"></a>Class <code>rw_timed_mutex</code>
constructors and destructor</h4>
<pre>
rw_timed_mutex(rw_scheduling_policy sp=sp_writer_priority);
</pre>
<dl class="function-semantics">
<dt><b>Postconditions:</b> <code>*this</code> is in the NO_LOCK state.</dt>
</dl>
<pre>
~rw_timed_mutex();
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>*this</code> is in the NO_LOCK state.</dt>
<dt><b>Effects:</b> Destroys <code>*this</code>.</dt>
<dt><b>Danger:</b> Destruction of a locked rw_mutex is a serious programming
error resulting in undefined behavior such as a program crash.</dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
<pre>
#include <a href="../../../boost/thread/rw_mutex.hpp">&lt;boost/thread/rw_mutex.hpp&gt;</a>
#include &lt;boost/thread/mutex.hpp&gt;
#include <a href="../../../boost/thread/thread.hpp">&lt;boost/thread/thread.hpp&gt;</a>
#include &lt;iostream&gt;
boost::mutex io_mutex; // The iostreams are not guaranteed to be <a href="definitions.html#Thread-safe">thread-safe</a>!
class counter
{
public:
counter() : count(0) { }
int increment() {
boost::rw_mutex::scoped_lock scoped_rw_lock(rw_mutex);
return ++count;
}
int get() {
boost::rw_mutex::scoped_lock scoped_rw_lock(rw_mutex,SHARED_LOCK);
return count;
}
private:
boost::rw_mutex rwm(boost::sp_writer_priority);
int count;
};
counter c;
void change_count(void*)
{
int i = c.increment();
boost::rw_mutex::scoped_lock scoped_lock(io_mutex);
std::cout &lt;&lt; "count == " &lt;&lt; i &lt;&lt; std::endl;
}
void get_count(void*)
{
int i = c.get();
boost::rw_mutex::scoped_lock scoped_lock(io_mutex);
std::cout &lt;&lt; "get_count == " &lt;&lt; i &lt;&lt; std::endl;
}
int main(int, char*[])
{
const int num_threads = 4;
boost::thread_group thrds;
for (int i=0; i &lt; num_threads; ++i)
{
thrds.create_thread(&amp;change_count, 0);
thrds.create_thread(&amp;get_count,0);
}
thrds.join_all();
return 0;
}
</pre>
<p>Typicial output might be:</p>
<pre>
count == 1
get_count == 1
get_count == 1
count == 2
count == 3
get_count == 3
count == 4
get_count == 4
</pre>
<p>Of course, exact output is platform dependent since the locking behavior with
competing readers and writers is undefined.</p>
<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>&copy; Copyright <a href="mailto:{{address}}">{{author}}</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>