[12] | 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> |
---|