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.overview" last-revision="$Date: 2004/07/17 04:33:59 $"> |
---|
8 | <title>Overview</title> |
---|
9 | <section id="threads.introduction"> |
---|
10 | <title>Introduction</title> |
---|
11 | <para>&Boost.Threads; allows C++ programs to execute as multiple, |
---|
12 | asynchronous, independent threads-of-execution. Each thread has its own |
---|
13 | machine state including program instruction counter and registers. Programs |
---|
14 | which execute as multiple threads are called multithreaded programs to |
---|
15 | distinguish them from traditional single-threaded programs. The <link |
---|
16 | linkend="threads.glossary">glossary</link> gives a more complete description |
---|
17 | of the multithreading execution environment.</para> |
---|
18 | <para>Multithreading provides several advantages: |
---|
19 | <itemizedlist> |
---|
20 | <listitem> |
---|
21 | <para>Programs which would otherwise block waiting for some external |
---|
22 | event can continue to respond if the blocking operation is placed in a |
---|
23 | separate thread. Multithreading is usually an absolute requirement for |
---|
24 | these programs.</para> |
---|
25 | </listitem> |
---|
26 | <listitem> |
---|
27 | <para>Well-designed multithreaded programs may execute faster than |
---|
28 | single-threaded programs, particularly on multiprocessor hardware. |
---|
29 | Note, however, that poorly-designed multithreaded programs are often |
---|
30 | slower than single-threaded programs.</para> |
---|
31 | </listitem> |
---|
32 | <listitem> |
---|
33 | <para>Some program designs may be easier to formulate using a |
---|
34 | multithreaded approach. After all, the real world is |
---|
35 | asynchronous!</para> |
---|
36 | </listitem> |
---|
37 | </itemizedlist></para> |
---|
38 | </section> |
---|
39 | <section> |
---|
40 | <title>Dangers</title> |
---|
41 | <section> |
---|
42 | <title>General considerations</title> |
---|
43 | <para>Beyond the errors which can occur in single-threaded programs, |
---|
44 | multithreaded programs are subject to additional errors: |
---|
45 | <itemizedlist> |
---|
46 | <listitem> |
---|
47 | <para><link linkend="threads.glossary.race-condition">Race |
---|
48 | conditions</link></para> |
---|
49 | </listitem> |
---|
50 | <listitem> |
---|
51 | <para><link linkend="threads.glossary.deadlock">Deadlock</link> |
---|
52 | (sometimes called "deadly embrace")</para> |
---|
53 | </listitem> |
---|
54 | <listitem> |
---|
55 | <para><link linkend="threads.glossary.priority-failure">Priority |
---|
56 | failures</link> (priority inversion, infinite overtaking, starvation, |
---|
57 | etc.)</para> |
---|
58 | </listitem> |
---|
59 | </itemizedlist></para> |
---|
60 | <para>Every multithreaded program must be designed carefully to avoid these |
---|
61 | errors. These aren't rare or exotic failures - they are virtually guaranteed |
---|
62 | to occur unless multithreaded code is designed to avoid them. Priority |
---|
63 | failures are somewhat less common, but are nonetheless serious.</para> |
---|
64 | <para>The <link linkend="threads.design">&Boost.Threads; design</link> |
---|
65 | attempts to minimize these errors, but they will still occur unless the |
---|
66 | programmer proactively designs to avoid them.</para> |
---|
67 | <note>Please also see <xref linkend="threads.implementation_notes"/> |
---|
68 | for additional, implementation-specific considerations.</note> |
---|
69 | </section> |
---|
70 | <section> |
---|
71 | <title>Testing and debugging considerations</title> |
---|
72 | <para>Multithreaded programs are non-deterministic. In other words, the |
---|
73 | same program with the same input data may follow different execution |
---|
74 | paths each time it is invoked. That can make testing and debugging a |
---|
75 | nightmare: |
---|
76 | <itemizedlist> |
---|
77 | <listitem> |
---|
78 | <para>Failures are often not repeatable.</para> |
---|
79 | </listitem> |
---|
80 | <listitem> |
---|
81 | <para>Probe effect causes debuggers to produce very different results |
---|
82 | from non-debug uses.</para> |
---|
83 | </listitem> |
---|
84 | <listitem> |
---|
85 | <para>Debuggers require special support to show thread state.</para> |
---|
86 | </listitem> |
---|
87 | <listitem> |
---|
88 | <para>Tests on a single processor system may give no indication of |
---|
89 | serious errors which would appear on multiprocessor systems, and visa |
---|
90 | versa. Thus test cases should include a varying number of |
---|
91 | processors.</para> |
---|
92 | </listitem> |
---|
93 | <listitem> |
---|
94 | <para>For programs which create a varying number of threads according |
---|
95 | to workload, tests which don't span the full range of possibilities |
---|
96 | may miss serious errors.</para> |
---|
97 | </listitem> |
---|
98 | </itemizedlist></para> |
---|
99 | </section> |
---|
100 | <section> |
---|
101 | <title>Getting a head start</title> |
---|
102 | <para>Although it might appear that multithreaded programs are inherently |
---|
103 | unreliable, many reliable multithreaded programs do exist. Multithreading |
---|
104 | techniques are known which lead to reliable programs.</para> |
---|
105 | <para>Design patterns for reliable multithreaded programs, including the |
---|
106 | important <emphasis>monitor</emphasis> pattern, are presented in |
---|
107 | <emphasis>Pattern-Oriented Software Architecture Volume 2 - Patterns for |
---|
108 | Concurrent and Networked Objects</emphasis> |
---|
109 | &cite.SchmidtStalRohnertBuschmann;. Many important multithreading programming |
---|
110 | considerations (independent of threading library) are discussed in |
---|
111 | <emphasis>Programming with POSIX Threads</emphasis> &cite.Butenhof97;.</para> |
---|
112 | <para>Doing some reading before attempting multithreaded designs will |
---|
113 | give you a head start toward reliable multithreaded programs.</para> |
---|
114 | </section> |
---|
115 | </section> |
---|
116 | <section> |
---|
117 | <title>C++ Standard Library usage in multithreaded programs</title> |
---|
118 | <section> |
---|
119 | <title>Runtime libraries</title> |
---|
120 | <para> |
---|
121 | <emphasis role="bold">Warning:</emphasis> Multithreaded programs such as |
---|
122 | those using &Boost.Threads; must link to <link |
---|
123 | linkend="threads.glossary.thread-safe">thread-safe</link> versions of |
---|
124 | all runtime libraries used by the program, including the runtime library |
---|
125 | for the C++ Standard Library. Failure to do so will cause <link |
---|
126 | linkend="threads.glossary.race-condition">race conditions</link> to occur |
---|
127 | when multiple threads simultaneously execute runtime library functions for |
---|
128 | <code>new</code>, <code>delete</code>, or other language features which |
---|
129 | imply shared state.</para> |
---|
130 | </section> |
---|
131 | <section> |
---|
132 | <title>Potentially non-thread-safe functions</title> |
---|
133 | <para>Certain C++ Standard Library functions inherited from C are |
---|
134 | particular problems because they hold internal state between |
---|
135 | calls: |
---|
136 | <itemizedlist> |
---|
137 | <listitem> |
---|
138 | <para><code>rand</code></para> |
---|
139 | </listitem> |
---|
140 | <listitem> |
---|
141 | <para><code>strtok</code></para> |
---|
142 | </listitem> |
---|
143 | <listitem> |
---|
144 | <para><code>asctime</code></para> |
---|
145 | </listitem> |
---|
146 | <listitem> |
---|
147 | <para><code>ctime</code></para> |
---|
148 | </listitem> |
---|
149 | <listitem> |
---|
150 | <para><code>gmtime</code></para> |
---|
151 | </listitem> |
---|
152 | <listitem> |
---|
153 | <para><code>localtime</code></para> |
---|
154 | </listitem> |
---|
155 | </itemizedlist></para> |
---|
156 | <para>It is possible to write thread-safe implementations of these by |
---|
157 | using thread specific storage (see |
---|
158 | <classname>boost::thread_specific_ptr</classname>), and several C++ |
---|
159 | compiler vendors do just that. The technique is well-know and is explained |
---|
160 | in &cite.Butenhof97;.</para> |
---|
161 | <para>But at least one vendor (HP-UX) does not provide thread-safe |
---|
162 | implementations of the above functions in their otherwise thread-safe |
---|
163 | runtime library. Instead they provide replacement functions with |
---|
164 | different names and arguments.</para> |
---|
165 | <para><emphasis role="bold">Recommendation:</emphasis> For the most |
---|
166 | portable, yet thread-safe code, use Boost replacements for the problem |
---|
167 | functions. See the <libraryname>Boost Random Number Library</libraryname> |
---|
168 | and <libraryname>Boost Tokenizer Library</libraryname>.</para> |
---|
169 | </section> |
---|
170 | </section> |
---|
171 | <section> |
---|
172 | <title>Common guarantees for all &Boost.Threads; components</title> |
---|
173 | <section> |
---|
174 | <title>Exceptions</title> |
---|
175 | <para>&Boost.Threads; destructors never |
---|
176 | throw exceptions. Unless otherwise specified, other |
---|
177 | &Boost.Threads; functions that do not have |
---|
178 | an exception-specification may throw implementation-defined |
---|
179 | exceptions.</para> |
---|
180 | <para>In particular, &Boost.Threads; |
---|
181 | reports failure to allocate storage by throwing an exception of type |
---|
182 | <code>std::bad_alloc</code> or a class derived from |
---|
183 | <code>std::bad_alloc</code>, failure to obtain thread resources other than |
---|
184 | memory by throwing an exception of type |
---|
185 | <classname>boost::thread_resource_error</classname>, and certain lock |
---|
186 | related failures by throwing an exception of type |
---|
187 | <classname>boost::lock_error</classname>.</para> |
---|
188 | <para><emphasis role="bold">Rationale:</emphasis> Follows the C++ Standard |
---|
189 | Library practice of allowing all functions except destructors or other |
---|
190 | specified functions to throw exceptions on errors.</para> |
---|
191 | </section> |
---|
192 | <section> |
---|
193 | <title>NonCopyable requirement</title> |
---|
194 | <para>&Boost.Threads; classes documented as |
---|
195 | meeting the NonCopyable requirement disallow copy construction and copy |
---|
196 | assignment. For the sake of exposition, the synopsis of such classes show |
---|
197 | private derivation from <classname>boost::noncopyable</classname>. Users |
---|
198 | should not depend on this derivation, however, as implementations are free |
---|
199 | to meet the NonCopyable requirement in other ways.</para> |
---|
200 | </section> |
---|
201 | </section> |
---|
202 | </section> |
---|