2
0
mirror of https://github.com/boostorg/thread.git synced 2026-01-23 06:02:14 +00:00
Files
thread/doc/faq.html
William E. Kempf 9b8c62d45a Merged from RC_1_29_0
[SVN r16126]
2002-11-05 22:43:42 +00:00

184 lines
9.5 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 - FAQ</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">Frequently Asked Questions (FAQs)</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#question1">1. Are lock objects thread safe?</a></dt>
<dt><a href="#question2a">2a. Why was <b>Boost.Threads</b> modeled after (specific
library name)?</a></dt>
<dt><a href="#question2b">2b. Why wasn't <b>Boost.Threads</b> modeled after
(specific library name)?</a></dt>
<dt><a href="#question3">3. Why do mutexes have noncopyable semantics?</a></dt>
<dt><a href="#question4">4. How can you prevent deadlock from occurring when
a thread must lock multiple mutexes?</a></dt>
<dt><a href="#question5">5. Don't noncopyable mutex semantics mean that a class
with a mutex member will be noncopyable as well?</a></dt>
<dt><a href="#question6">6. How can you lock a mutex member in a const member
function (in order to implement the monitor pattern)?</a></dt>
<dt><a href="#question7">7. Why supply condition variables rather than event
variables?</a></dt>
<dt><a href="#question8">8. Why isn't thread cancellation or termination provided?</a></dt>
<dt><a href="#question9">9. Is it safe for threads to share automatic storage
duration (stack) objects via pointers or references?</a></dt>
<dt><a href="#question10">10. Why has class semaphore disappeared?</a></dt>
</dl>
<h2><a name="question1"></a>1. Are lock objects <a href="definitions.html#definition-thread-safe">
thread safe</a>?</h2>
<p><b>No!</b> Lock objects are not meant to be shared between threads. They are
meant to be short-lived objects created on automatic storage within a code block.
Any other usage is just likely to lead to errors and won&#39;t really be of
actual benefit any way. Share <a href=
"mutex_concept.html">mutexes</a>, not locks. For more information see
the <a href="rationale.html#lock_objects">rationale</a> behind the design for
lock objects.</p>
<h2><a name="question2a"></a>2a. Why was <b>Boost.Threads</b> modeled after (specific
library name)?</h2>
<p>It wasn&#39;t. Boost.Threads was designed from scratch. Extensive design discussions
involved numerous people representing a wide range of experience across many
platforms. To ensure portability, the initial implements were done in parallel
using POSIX Threads and the Win32 threading API. But the Boost.Threads design
is very much in the spirit of C++, and thus doesn&#39;t model such C based APIs.</p>
<h2><a name="question2b"></a>2b. Why wasn&#39;t Boost.Threads modeled after (specific
library name)?</h2>
<p>Existing C++ libraries either seemed dangerous (often failing to take advantage
of prior art to reduce errors) or had excessive dependencies on library components
unrelated to threading. Existing C libraries couldn&#39;t meet our C++ requirements,
and were also missing certain features. For instance, the WIN32 thread API lacks
condition variables, even though these are critical for the important Monitor
pattern <a href="bibliography.html#Schmidt-00">[Schmidt 00]</a>.</p>
<h2><a name="question3"></a>3. Why do <a href="mutex_concept.html">Mutexes</a>
have noncopyable semantics?</h2>
<p>To ensure that <a href="definitions.html#Deadlock">deadlocks</a> don&#39;t
occur. The only logical form of copy would be to use some sort of shallow copy
semantics in which multiple mutex objects could refer to the same mutex state.
This means that if ObjA has a mutex object as part of its state and ObjB is
copy constructed from it, then when ObjB::foo() locks the mutex it has effectively
locked ObjA as well. This behavior can result in deadlock. Other copy semantics
result in similar problems (if you think you can prove this to be wrong then
supply us with an alternative and we&#39;ll reconsider).</p>
<h2><a name="question4"></a>4. How can you prevent <a href="definitions.html#Deadlock">
deadlock</a> from occurring when a thread must lock multiple mutexes?</h2>
<p>Always lock them in the same order. One easy way of doing this is to use each
mutex&#39;s address to determine the order in which they are locked. A future
Boost.Threads concept may wrap this pattern up in a reusable class.</p>
<h2><a name="question5"></a>5. Don&#39;t noncopyable <a href="mutex_concept.html">mutex</a>
semantics mean that a class with a mutex member will be noncopyable as well?</h2>
<p>No, but what it does mean is that the compiler can&#39;t generate a copy constructor
and assignment operator, so they will have to be coded explicitly. This is a
<b>good thing</b>, however, since the compiler generated operations would not
be <a href=
"definitions.html#Thread-safe">thread-safe</a>. The following is a simple
example of a class with copyable semantics and internal synchronization through
a mutex member.</p>
<pre>
class counter
{
public:
// Doesn't need synchronization since there can be no references to *this
// until after it's constructed!
explicit counter(int initial_value)
: m_value(initial_value)
{
}
// We only need to synchronize other for the same reason we don't have to
// synchronize on construction!
counter(const counter&amp; other)
{
boost::mutex::scoped_lock scoped_lock(other.m_mutex);
m_value = other.m_value;
}
// For assignment we need to synchronize both objects!
const counter&amp; operator=(const counter&amp; other)
{
if (this == &amp;other)
return *this;
boost::mutex::scoped_lock lock1(&amp;m_mutex &lt; &amp;other.m_mutex ? m_mutex : other.m_mutex);
boost::mutex::scoped_lock lock2(&amp;m_mutex &gt; &amp;other.m_mutex ? m_mutex : other.m_mutex);
m_value = other.m_value;
return *this;
}
int value() const
{
boost::mutex::scoped_lock scoped_lock(m_mutex);
return m_value;
}
int increment()
{
boost::mutex::scoped_lock scoped_lock(m_mutex);
return ++m_value;
}
private:
mutable boost::mutex m_mutex;
int m_value;
};
</pre>
<h2><a name="question6"></a>6. How can you lock a <a href="mutex_concept.html">mutex</a>
member in a const member function, in order to implement the Monitor Pattern?</h2>
<p>The Monitor Pattern mutex <a href="bibliography.html#Schmidt-00"> [Schmidt
00]</a> should simply be declared as mutable. See the example code above. The
internal state of mutex types could have been made mutable, with all lock calls
made via const functions, but this does a poor job of documenting the actual
semantics (and in fact would be incorrect since the logical state of a locked
mutex clearly differs from the logical state of an unlocked mutex). Declaring
a mutex member as mutable clearly documents the intended semantics.</p>
<h2><a name="question7"></a>7. Why supply <a href="condition.html">condition variables</a>
rather than <a href="rationale.html#Events">event variables</a>?</h2>
<p>Condition variables result in user code much less prone to <a href=
"definitions.html#Race condition">race conditions</a> than event variables.
See <a href="rationale.html#Events">Rationale</a> for analysis. Also see <a href="bibliography.html#Hoare-74">[Hoare
74]</a> and <a href="bibliography.html#Schmidt-00">[Schmidt 00]</a>.</p>
<h2><a name="question8"></a>8. Why isn&#39;t thread cancellation or termination
provided?</h2>
<p>There&#39;s a valid need for thread termination, so at some point Boost.Threads
probably will include it, but only after we can find a truly safe (and portable)
mechanism for this concept.</p>
<h2><a name="question9"></a>9. Is it safe for threads to share automatic storage
duration (stack) objects via pointers or references?</h2>
<p>Only if you can guarantee that the lifetime of the stack object will not end
while other threads might still access the object. Thus the safest practice
is to avoid sharing stack objects, particularly in designs where threads are
created and destroyed dynamically. Restrict sharing of stack objects to simple
designs with very clear and unchanging function and thread lifetimes. (Suggested
by Darryl Green).</p>
<h2><a name="question10"></a>10. Why has class semaphore disappeared?</h2>
<p>Semaphore was removed as too error prone. The same effect can be achieved with
greater safety by the combination of a mutex and a condition variable.</p>
<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>&copy; Copyright <a href="mailto:wekempf@cox.net">William E. Kempf</a> 2001-2002.
All Rights Reserved.</i></p>
<p>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation. William E. Kempf
makes no representations about the suitability of this software for any purpose.
It is provided &quot;as is&quot; without express or implied warranty.</p>
</body>
</html>