Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/thread/doc/faq.xml @ 14

Last change on this file since 14 was 12, checked in by landauf, 17 years ago

added boost

File size: 8.1 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
3  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
4  <!ENTITY % threads.entities SYSTEM "entities.xml">
5  %threads.entities;
6]>
7<section id="threads.faq" last-revision="$Date: 2004/07/17 04:33:59 $">
8  <title>Frequently Asked Questions</title>
9  <qandaset>
10    <qandaentry>
11          <question>
12            <para>Are lock objects <link
13                linkend="threads.glossary.thread-safe">thread safe</link>?</para>
14          </question>
15          <answer>
16            <para><emphasis role="bold">No!</emphasis> Lock objects are not meant to
17                be shared between threads. They are meant to be short-lived objects
18                created on automatic storage within a code block. Any other usage is
19                just likely to lead to errors and won't really be of actual benefit anyway.
20                Share <link linkend="threads.concepts.mutexes">Mutexes</link>, not
21                Locks. For more information see the <link
22                linkend="threads.rationale.locks">rationale</link> behind the
23                design for lock objects.</para>
24          </answer>
25        </qandaentry>
26    <qandaentry>
27      <question>
28            <para>Why was &Boost.Threads; modeled after (specific library
29                name)?</para>
30          </question>
31          <answer>
32            <para>It wasn't. &Boost.Threads; was designed from scratch. Extensive
33                design discussions involved numerous people representing a wide range of
34                experience across many platforms. To ensure portability, the initial
35                implements were done in parallel using POSIX Threads and the Win32
36                threading API. But the &Boost.Threads; design is very much in the spirit
37                of C++, and thus doesn't model such C based APIs.</para>
38          </answer>
39        </qandaentry>
40        <qandaentry>
41          <question>
42            <para>Why wasn't &Boost.Threads; modeled after (specific library
43            name)?</para>
44          </question>
45          <answer>
46        <para>Existing C++ libraries either seemed dangerous (often failing to
47                take advantage of prior art to reduce errors) or had excessive
48                dependencies on library components unrelated to threading. Existing C
49                libraries couldn't meet our C++ requirements, and were also missing
50                certain features. For instance, the WIN32 thread API lacks condition
51                variables, even though these are critical for the important Monitor
52                pattern &cite.SchmidtStalRohnertBuschmann;.</para>
53      </answer>
54        </qandaentry>
55        <qandaentry>
56          <question>
57            <para>Why do <link linkend="threads.concepts.mutexes">Mutexes</link>
58                have noncopyable semantics?</para>
59          </question>
60          <answer>
61        <para>To ensure that <link
62                linkend="threads.glossary.deadlock">deadlocks</link> don't occur. The
63                only logical form of copy would be to use some sort of shallow copy
64                semantics in which multiple mutex objects could refer to the same mutex
65                state. This means that if ObjA has a mutex object as part of its state
66                and ObjB is copy constructed from it, then when ObjB::foo() locks the
67                mutex it has effectively locked ObjA as well. This behavior can result
68                in deadlock. Other copy semantics result in similar problems (if you
69                think you can prove this to be wrong then supply us with an alternative
70                and we'll reconsider).</para>
71          </answer>
72        </qandaentry>
73        <qandaentry>
74          <question>
75            <para>How can you prevent <link
76                linkend="threads.glossary.deadlock">deadlock</link> from occurring when
77                a thread must lock multiple mutexes?</para>
78          </question>
79          <answer>
80            <para>Always lock them in the same order. One easy way of doing this is
81                to use each mutex's address to determine the order in which they are
82                locked. A future &Boost.Threads; concept may wrap this pattern up in a
83                reusable class.</para>
84          </answer>
85        </qandaentry>
86        <qandaentry>
87          <question>
88            <para>Don't noncopyable <link
89                linkend="threads.concepts.mutexes">Mutex</link> semantics mean that a
90                class with a mutex member will be noncopyable as well?</para>
91          </question>
92          <answer>
93            <para>No, but what it does mean is that the compiler can't generate a
94                copy constructor and assignment operator, so they will have to be coded
95                explicitly. This is a <emphasis role="bold">good thing</emphasis>,
96                however, since the compiler generated operations would not be <link
97                linkend="threads.glossary.thread-safe">thread-safe</link>. The following
98                is a simple example of a class with copyable semantics and internal
99        synchronization through a mutex member.</para>
100<programlisting>
101class counter
102{
103public:
104   // Doesn't need synchronization since there can be no references to *this
105   // until after it's constructed!
106   explicit counter(int initial_value)
107      : m_value(initial_value)
108   {
109   }
110   // We only need to synchronize other for the same reason we don't have to
111   // synchronize on construction!
112   counter(const counter&amp; other)
113   {
114      boost::mutex::scoped_lock scoped_lock(other.m_mutex);
115      m_value = other.m_value;
116   }
117   // For assignment we need to synchronize both objects!
118   const counter&amp; operator=(const counter&amp; other)
119   {
120      if (this == &amp;other)
121         return *this;
122      boost::mutex::scoped_lock lock1(&amp;m_mutex &lt; &amp;other.m_mutex ? m_mutex : other.m_mutex);
123      boost::mutex::scoped_lock lock2(&amp;m_mutex &gt; &amp;other.m_mutex ? m_mutex : other.m_mutex);
124      m_value = other.m_value;
125      return *this;
126   }
127   int value() const
128   {
129      boost::mutex::scoped_lock scoped_lock(m_mutex);
130      return m_value;
131   }
132   int increment()
133   {
134      boost::mutex::scoped_lock scoped_lock(m_mutex);
135      return ++m_value;
136   }
137private:
138   mutable boost::mutex m_mutex;
139   int m_value;
140};
141</programlisting>
142      </answer>
143        </qandaentry>
144        <qandaentry>
145          <question>
146            <para>How can you lock a <link
147                linkend="threads.concepts.mutexes">Mutex</link> member in a const member
148                function, in order to implement the Monitor Pattern?</para>
149          </question>
150          <answer>
151            <para>The Monitor Pattern &cite.SchmidtStalRohnertBuschmann; mutex
152                should simply be declared as mutable. See the example code above. The
153                internal state of mutex types could have been made mutable, with all
154                lock calls made via const functions, but this does a poor job of
155                documenting the actual semantics (and in fact would be incorrect since
156                the logical state of a locked mutex clearly differs from the logical
157                state of an unlocked mutex). Declaring a mutex member as mutable clearly
158                documents the intended semantics.</para>
159          </answer>
160        </qandaentry>
161        <qandaentry>
162          <question>
163            <para>Why supply <classname>boost::condition</classname> variables rather than
164                event variables?</para>
165          </question>
166          <answer>
167            <para>Condition variables result in user code much less prone to <link
168                linkend="threads.glossary.race-condition">race conditions</link> than
169                event variables. See <xref linkend="threads.rationale.events" /> 
170                for analysis. Also see &cite.Hoare74; and &cite.SchmidtStalRohnertBuschmann;.
171                </para>
172          </answer>
173        </qandaentry>
174        <qandaentry>
175          <question>
176            <para>Why isn't thread cancellation or termination provided?</para>
177          </question>
178          <answer>
179            <para>There's a valid need for thread termination, so at some point
180                &Boost.Threads; probably will include it, but only after we can find a
181                truly safe (and portable) mechanism for this concept.</para>
182          </answer>
183        </qandaentry>
184        <qandaentry>
185          <question>
186            <para>Is it safe for threads to share automatic storage duration (stack)
187                objects via pointers or references?</para>
188          </question>
189          <answer>
190            <para>Only if you can guarantee that the lifetime of the stack object
191                will not end while other threads might still access the object. Thus the
192                safest practice is to avoid sharing stack objects, particularly in
193                designs where threads are created and destroyed dynamically. Restrict
194                sharing of stack objects to simple designs with very clear and
195                unchanging function and thread lifetimes. (Suggested by Darryl
196                Green).</para>
197          </answer>
198        </qandaentry>
199        <qandaentry>
200          <question>
201            <para>Why has class semaphore disappeared?</para>
202          </question>
203          <answer>
204            <para>Semaphore was removed as too error prone. The same effect can be
205                achieved with greater safety by the combination of a mutex and a
206                condition variable.</para>
207          </answer>
208        </qandaentry>
209  </qandaset>
210</section>
Note: See TracBrowser for help on using the repository browser.