mirror of
https://github.com/boostorg/thread.git
synced 2026-01-23 18:12:12 +00:00
184 lines
9.6 KiB
HTML
184 lines
9.6 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'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'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't model such C based APIs.</p>
|
|
<h2><a name="question2b"></a>2b. Why wasn'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'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'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'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'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'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'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& 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& operator=(const counter& other)
|
|
{
|
|
if (this == &other)
|
|
return *this;
|
|
|
|
boost::mutex::scoped_lock lock1(&m_mutex < &other.m_mutex ? m_mutex : other.m_mutex);
|
|
boost::mutex::scoped_lock lock2(&m_mutex > &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't thread cancellation or termination
|
|
provided?</h2>
|
|
<p>There'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>© 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 "as is" without express or implied warranty.</p>
|
|
</body>
|
|
</html>
|