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