1 |
742 |
jeremybenn |
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2 |
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
3 |
|
|
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Concurrency</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"/><meta name="keywords" content=" ISO C++ , library "/><meta name="keywords" content=" ISO C++ , runtime , library "/><link rel="home" href="../index.html" title="The GNU C++ Library"/><link rel="up" href="using.html" title="Chapter 3. Using"/><link rel="prev" href="using_dynamic_or_shared.html" title="Linking"/><link rel="next" href="using_exceptions.html" title="Exceptions"/></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Concurrency</th></tr><tr><td align="left"><a accesskey="p" href="using_dynamic_or_shared.html">Prev</a> </td><th width="60%" align="center">Chapter 3. Using</th><td align="right"> <a accesskey="n" href="using_exceptions.html">Next</a></td></tr></table><hr/></div><div class="section" title="Concurrency"><div class="titlepage"><div><div><h2 class="title"><a id="manual.intro.using.concurrency"/>Concurrency</h2></div></div></div><p>This section discusses issues surrounding the proper compilation
|
4 |
|
|
of multithreaded applications which use the Standard C++
|
5 |
|
|
library. This information is GCC-specific since the C++
|
6 |
|
|
standard does not address matters of multithreaded applications.
|
7 |
|
|
</p><div class="section" title="Prerequisites"><div class="titlepage"><div><div><h3 class="title"><a id="manual.intro.using.concurrency.prereq"/>Prerequisites</h3></div></div></div><p>All normal disclaimers aside, multithreaded C++ application are
|
8 |
|
|
only supported when libstdc++ and all user code was built with
|
9 |
|
|
compilers which report (via <code class="code"> gcc/g++ -v </code>) the same thread
|
10 |
|
|
model and that model is not <span class="emphasis"><em>single</em></span>. As long as your
|
11 |
|
|
final application is actually single-threaded, then it should be
|
12 |
|
|
safe to mix user code built with a thread model of
|
13 |
|
|
<span class="emphasis"><em>single</em></span> with a libstdc++ and other C++ libraries built
|
14 |
|
|
with another thread model useful on the platform. Other mixes
|
15 |
|
|
may or may not work but are not considered supported. (Thus, if
|
16 |
|
|
you distribute a shared C++ library in binary form only, it may
|
17 |
|
|
be best to compile it with a GCC configured with
|
18 |
|
|
--enable-threads for maximal interchangeability and usefulness
|
19 |
|
|
with a user population that may have built GCC with either
|
20 |
|
|
--enable-threads or --disable-threads.)
|
21 |
|
|
</p><p>When you link a multithreaded application, you will probably
|
22 |
|
|
need to add a library or flag to g++. This is a very
|
23 |
|
|
non-standardized area of GCC across ports. Some ports support a
|
24 |
|
|
special flag (the spelling isn't even standardized yet) to add
|
25 |
|
|
all required macros to a compilation (if any such flags are
|
26 |
|
|
required then you must provide the flag for all compilations not
|
27 |
|
|
just linking) and link-library additions and/or replacements at
|
28 |
|
|
link time. The documentation is weak. Here is a quick summary
|
29 |
|
|
to display how ad hoc this is: On Solaris, both -pthreads and
|
30 |
|
|
-threads (with subtly different meanings) are honored. On OSF,
|
31 |
|
|
-pthread and -threads (with subtly different meanings) are
|
32 |
|
|
honored. On GNU/Linux x86, -pthread is honored. On FreeBSD,
|
33 |
|
|
-pthread is honored. Some other ports use other switches.
|
34 |
|
|
AFAIK, none of this is properly documented anywhere other than
|
35 |
|
|
in ``gcc -dumpspecs'' (look at lib and cpp entries).
|
36 |
|
|
</p></div><div class="section" title="Thread Safety"><div class="titlepage"><div><div><h3 class="title"><a id="manual.intro.using.concurrency.thread_safety"/>Thread Safety</h3></div></div></div><p>
|
37 |
|
|
In the terms of the 2011 C++ standard a thread-safe program is one which
|
38 |
|
|
does not perform any conflicting non-atomic operations on memory locations
|
39 |
|
|
and so does not contain any data races.
|
40 |
|
|
The standard places requirements on the library to ensure that no data
|
41 |
|
|
races are caused by the library itself or by programs which use the
|
42 |
|
|
library correctly (as described below).
|
43 |
|
|
The C++11 memory model and library requirements are a more formal version
|
44 |
|
|
of the <a class="link" href="http://www.sgi.com/tech/stl/thread_safety.html">SGI STL</a> definition of thread safety, which the library used
|
45 |
|
|
prior to the 2011 standard.
|
46 |
|
|
</p><p>The library strives to be thread-safe when all of the following
|
47 |
|
|
conditions are met:
|
48 |
|
|
</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p>The system's libc is itself thread-safe,
|
49 |
|
|
</p></li><li class="listitem"><p>
|
50 |
|
|
The compiler in use reports a thread model other than
|
51 |
|
|
'single'. This can be tested via output from <code class="code">gcc
|
52 |
|
|
-v</code>. Multi-thread capable versions of gcc output
|
53 |
|
|
something like this:
|
54 |
|
|
</p><pre class="programlisting">
|
55 |
|
|
%gcc -v
|
56 |
|
|
Using built-in specs.
|
57 |
|
|
...
|
58 |
|
|
Thread model: posix
|
59 |
|
|
gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)
|
60 |
|
|
</pre><p>Look for "Thread model" lines that aren't equal to "single."</p></li><li class="listitem"><p>
|
61 |
|
|
Requisite command-line flags are used for atomic operations
|
62 |
|
|
and threading. Examples of this include <code class="code">-pthread</code>
|
63 |
|
|
and <code class="code">-march=native</code>, although specifics vary
|
64 |
|
|
depending on the host environment. See <a class="link" href="http://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html">Machine
|
65 |
|
|
Dependent Options</a>.
|
66 |
|
|
</p></li><li class="listitem"><p>
|
67 |
|
|
An implementation of atomicity.h functions
|
68 |
|
|
exists for the architecture in question. See the internals documentation for more <a class="link" href="internals.html#internals.thread_safety" title="Thread Safety">details</a>.
|
69 |
|
|
</p></li></ul></div><p>The user code must guard against concurrent function calls which
|
70 |
|
|
access any particular library object's state when one or more of
|
71 |
|
|
those accesses modifies the state. An object will be modified by
|
72 |
|
|
invoking a non-const member function on it or passing it as a
|
73 |
|
|
non-const argument to a library function. An object will not be
|
74 |
|
|
modified by invoking a const member function on it or passing it to
|
75 |
|
|
a function as a pointer- or reference-to-const.
|
76 |
|
|
Typically, the application
|
77 |
|
|
programmer may infer what object locks must be held based on the
|
78 |
|
|
objects referenced in a function call and whether the objects are
|
79 |
|
|
accessed as const or non-const. Without getting
|
80 |
|
|
into great detail, here is an example which requires user-level
|
81 |
|
|
locks:
|
82 |
|
|
</p><pre class="programlisting">
|
83 |
|
|
library_class_a shared_object_a;
|
84 |
|
|
|
85 |
|
|
void thread_main () {
|
86 |
|
|
library_class_b *object_b = new library_class_b;
|
87 |
|
|
shared_object_a.add_b (object_b); // must hold lock for shared_object_a
|
88 |
|
|
shared_object_a.mutate (); // must hold lock for shared_object_a
|
89 |
|
|
}
|
90 |
|
|
|
91 |
|
|
// Multiple copies of thread_main() are started in independent threads.</pre><p>Under the assumption that object_a and object_b are never exposed to
|
92 |
|
|
another thread, here is an example that does not require any
|
93 |
|
|
user-level locks:
|
94 |
|
|
</p><pre class="programlisting">
|
95 |
|
|
void thread_main () {
|
96 |
|
|
library_class_a object_a;
|
97 |
|
|
library_class_b *object_b = new library_class_b;
|
98 |
|
|
object_a.add_b (object_b);
|
99 |
|
|
object_a.mutate ();
|
100 |
|
|
} </pre><p>All library types are safe to use in a multithreaded program
|
101 |
|
|
if objects are not shared between threads or as
|
102 |
|
|
long each thread carefully locks out access by any other
|
103 |
|
|
thread while it modifies any object visible to another thread.
|
104 |
|
|
Unless otherwise documented, the only exceptions to these rules
|
105 |
|
|
are atomic operations on the types in
|
106 |
|
|
<code class="filename"><atomic></code>
|
107 |
|
|
and lock/unlock operations on the standard mutex types in
|
108 |
|
|
<code class="filename"><mutex></code>. These
|
109 |
|
|
atomic operations allow concurrent accesses to the same object
|
110 |
|
|
without introducing data races.
|
111 |
|
|
</p><p>The following member functions of standard containers can be
|
112 |
|
|
considered to be const for the purposes of avoiding data races:
|
113 |
|
|
<code class="code">begin</code>, <code class="code">end</code>, <code class="code">rbegin</code>, <code class="code">rend</code>,
|
114 |
|
|
<code class="code">front</code>, <code class="code">back</code>, <code class="code">data</code>,
|
115 |
|
|
<code class="code">find</code>, <code class="code">lower_bound</code>, <code class="code">upper_bound</code>,
|
116 |
|
|
<code class="code">equal_range</code>, <code class="code">at</code>
|
117 |
|
|
and, except in associative or unordered associative containers,
|
118 |
|
|
<code class="code">operator[]</code>. In other words, although they are non-const
|
119 |
|
|
so that they can return mutable iterators, those member functions
|
120 |
|
|
will not modify the container.
|
121 |
|
|
Accessing an iterator might cause a non-modifying access to
|
122 |
|
|
the container the iterator refers to (for example incrementing a
|
123 |
|
|
list iterator must access the pointers between nodes, which are part
|
124 |
|
|
of the container and so conflict with other accesses to the container).
|
125 |
|
|
</p><p>Programs which follow the rules above will not encounter data
|
126 |
|
|
races in library code, even when using library types which share
|
127 |
|
|
state between distinct objects. In the example below the
|
128 |
|
|
<code class="code">shared_ptr</code> objects share a reference count, but
|
129 |
|
|
because the code does not perform any non-const operations on the
|
130 |
|
|
globally-visible object, the library ensures that the reference
|
131 |
|
|
count updates are atomic and do not introduce data races:
|
132 |
|
|
</p><pre class="programlisting">
|
133 |
|
|
std::shared_ptr<int> global_sp;
|
134 |
|
|
|
135 |
|
|
void thread_main() {
|
136 |
|
|
auto local_sp = global_sp; // OK, copy constructor's parameter is reference-to-const
|
137 |
|
|
|
138 |
|
|
int i = *global_sp; // OK, operator* is const
|
139 |
|
|
int j = *local_sp; // OK, does not operate on global_sp
|
140 |
|
|
|
141 |
|
|
// *global_sp = 2; // NOT OK, modifies int visible to other threads
|
142 |
|
|
// *local_sp = 2; // NOT OK, modifies int visible to other threads
|
143 |
|
|
|
144 |
|
|
// global_sp.reset(); // NOT OK, reset is non-const
|
145 |
|
|
local_sp.reset(); // OK, does not operate on global_sp
|
146 |
|
|
}
|
147 |
|
|
|
148 |
|
|
int main() {
|
149 |
|
|
global_sp.reset(new int(1));
|
150 |
|
|
std::thread t1(thread_main);
|
151 |
|
|
std::thread t2(thread_main);
|
152 |
|
|
t1.join();
|
153 |
|
|
t2.join();
|
154 |
|
|
}
|
155 |
|
|
</pre><p>For further details of the C++11 memory model see Hans-J. Boehm's
|
156 |
|
|
<a class="link" href="http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/user-faq.html">Threads
|
157 |
|
|
and memory model for C++</a> pages, particularly the <a class="link" href="http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/threadsintro.html">introduction</a>
|
158 |
|
|
and <a class="link" href="http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/user-faq.html">FAQ</a>.
|
159 |
|
|
</p></div><div class="section" title="Atomics"><div class="titlepage"><div><div><h3 class="title"><a id="manual.intro.using.concurrency.atomics"/>Atomics</h3></div></div></div><p>
|
160 |
|
|
</p></div><div class="section" title="IO"><div class="titlepage"><div><div><h3 class="title"><a id="manual.intro.using.concurrency.io"/>IO</h3></div></div></div><p>This gets a bit tricky. Please read carefully, and bear with me.
|
161 |
|
|
</p><div class="section" title="Structure"><div class="titlepage"><div><div><h4 class="title"><a id="concurrency.io.structure"/>Structure</h4></div></div></div><p>A wrapper
|
162 |
|
|
type called <code class="code">__basic_file</code> provides our abstraction layer
|
163 |
|
|
for the <code class="code">std::filebuf</code> classes. Nearly all decisions dealing
|
164 |
|
|
with actual input and output must be made in <code class="code">__basic_file</code>.
|
165 |
|
|
</p><p>A generic locking mechanism is somewhat in place at the filebuf layer,
|
166 |
|
|
but is not used in the current code. Providing locking at any higher
|
167 |
|
|
level is akin to providing locking within containers, and is not done
|
168 |
|
|
for the same reasons (see the links above).
|
169 |
|
|
</p></div><div class="section" title="Defaults"><div class="titlepage"><div><div><h4 class="title"><a id="concurrency.io.defaults"/>Defaults</h4></div></div></div><p>The __basic_file type is simply a collection of small wrappers around
|
170 |
|
|
the C stdio layer (again, see the link under Structure). We do no
|
171 |
|
|
locking ourselves, but simply pass through to calls to <code class="code">fopen</code>,
|
172 |
|
|
<code class="code">fwrite</code>, and so forth.
|
173 |
|
|
</p><p>So, for 3.0, the question of "is multithreading safe for I/O"
|
174 |
|
|
must be answered with, "is your platform's C library threadsafe
|
175 |
|
|
for I/O?" Some are by default, some are not; many offer multiple
|
176 |
|
|
implementations of the C library with varying tradeoffs of threadsafety
|
177 |
|
|
and efficiency. You, the programmer, are always required to take care
|
178 |
|
|
with multiple threads.
|
179 |
|
|
</p><p>(As an example, the POSIX standard requires that C stdio FILE*
|
180 |
|
|
operations are atomic. POSIX-conforming C libraries (e.g, on Solaris
|
181 |
|
|
and GNU/Linux) have an internal mutex to serialize operations on
|
182 |
|
|
FILE*s. However, you still need to not do stupid things like calling
|
183 |
|
|
<code class="code">fclose(fs)</code> in one thread followed by an access of
|
184 |
|
|
<code class="code">fs</code> in another.)
|
185 |
|
|
</p><p>So, if your platform's C library is threadsafe, then your
|
186 |
|
|
<code class="code">fstream</code> I/O operations will be threadsafe at the lowest
|
187 |
|
|
level. For higher-level operations, such as manipulating the data
|
188 |
|
|
contained in the stream formatting classes (e.g., setting up callbacks
|
189 |
|
|
inside an <code class="code">std::ofstream</code>), you need to guard such accesses
|
190 |
|
|
like any other critical shared resource.
|
191 |
|
|
</p></div><div class="section" title="Future"><div class="titlepage"><div><div><h4 class="title"><a id="concurrency.io.future"/>Future</h4></div></div></div><p> A
|
192 |
|
|
second choice may be available for I/O implementations: libio. This is
|
193 |
|
|
disabled by default, and in fact will not currently work due to other
|
194 |
|
|
issues. It will be revisited, however.
|
195 |
|
|
</p><p>The libio code is a subset of the guts of the GNU libc (glibc) I/O
|
196 |
|
|
implementation. When libio is in use, the <code class="code">__basic_file</code>
|
197 |
|
|
type is basically derived from FILE. (The real situation is more
|
198 |
|
|
complex than that... it's derived from an internal type used to
|
199 |
|
|
implement FILE. See libio/libioP.h to see scary things done with
|
200 |
|
|
vtbls.) The result is that there is no "layer" of C stdio
|
201 |
|
|
to go through; the filebuf makes calls directly into the same
|
202 |
|
|
functions used to implement <code class="code">fread</code>, <code class="code">fwrite</code>,
|
203 |
|
|
and so forth, using internal data structures. (And when I say
|
204 |
|
|
"makes calls directly," I mean the function is literally
|
205 |
|
|
replaced by a jump into an internal function. Fast but frightening.
|
206 |
|
|
*grin*)
|
207 |
|
|
</p><p>Also, the libio internal locks are used. This requires pulling in
|
208 |
|
|
large chunks of glibc, such as a pthreads implementation, and is one
|
209 |
|
|
of the issues preventing widespread use of libio as the libstdc++
|
210 |
|
|
cstdio implementation.
|
211 |
|
|
</p><p>But we plan to make this work, at least as an option if not a future
|
212 |
|
|
default. Platforms running a copy of glibc with a recent-enough
|
213 |
|
|
version will see calls from libstdc++ directly into the glibc already
|
214 |
|
|
installed. For other platforms, a copy of the libio subsection will
|
215 |
|
|
be built and included in libstdc++.
|
216 |
|
|
</p></div><div class="section" title="Alternatives"><div class="titlepage"><div><div><h4 class="title"><a id="concurrency.io.alt"/>Alternatives</h4></div></div></div><p>Don't forget that other cstdio implementations are possible. You could
|
217 |
|
|
easily write one to perform your own forms of locking, to solve your
|
218 |
|
|
"interesting" problems.
|
219 |
|
|
</p></div></div><div class="section" title="Containers"><div class="titlepage"><div><div><h3 class="title"><a id="manual.intro.using.concurrency.containers"/>Containers</h3></div></div></div><p>This section discusses issues surrounding the design of
|
220 |
|
|
multithreaded applications which use Standard C++ containers.
|
221 |
|
|
All information in this section is current as of the gcc 3.0
|
222 |
|
|
release and all later point releases. Although earlier gcc
|
223 |
|
|
releases had a different approach to threading configuration and
|
224 |
|
|
proper compilation, the basic code design rules presented here
|
225 |
|
|
were similar. For information on all other aspects of
|
226 |
|
|
multithreading as it relates to libstdc++, including details on
|
227 |
|
|
the proper compilation of threaded code (and compatibility between
|
228 |
|
|
threaded and non-threaded code), see Chapter 17.
|
229 |
|
|
</p><p>Two excellent pages to read when working with the Standard C++
|
230 |
|
|
containers and threads are
|
231 |
|
|
<a class="link" href="http://www.sgi.com/tech/stl/thread_safety.html">SGI's
|
232 |
|
|
http://www.sgi.com/tech/stl/thread_safety.html</a> and
|
233 |
|
|
<a class="link" href="http://www.sgi.com/tech/stl/Allocators.html">SGI's
|
234 |
|
|
http://www.sgi.com/tech/stl/Allocators.html</a>.
|
235 |
|
|
</p><p><span class="emphasis"><em>However, please ignore all discussions about the user-level
|
236 |
|
|
configuration of the lock implementation inside the STL
|
237 |
|
|
container-memory allocator on those pages. For the sake of this
|
238 |
|
|
discussion, libstdc++ configures the SGI STL implementation,
|
239 |
|
|
not you. This is quite different from how gcc pre-3.0 worked.
|
240 |
|
|
In particular, past advice was for people using g++ to
|
241 |
|
|
explicitly define _PTHREADS or other macros or port-specific
|
242 |
|
|
compilation options on the command line to get a thread-safe
|
243 |
|
|
STL. This is no longer required for any port and should no
|
244 |
|
|
longer be done unless you really know what you are doing and
|
245 |
|
|
assume all responsibility.</em></span>
|
246 |
|
|
</p><p>Since the container implementation of libstdc++ uses the SGI
|
247 |
|
|
code, we use the same definition of thread safety as SGI when
|
248 |
|
|
discussing design. A key point that beginners may miss is the
|
249 |
|
|
fourth major paragraph of the first page mentioned above
|
250 |
|
|
(<span class="emphasis"><em>For most clients...</em></span>), which points out that
|
251 |
|
|
locking must nearly always be done outside the container, by
|
252 |
|
|
client code (that'd be you, not us). There is a notable
|
253 |
|
|
exceptions to this rule. Allocators called while a container or
|
254 |
|
|
element is constructed uses an internal lock obtained and
|
255 |
|
|
released solely within libstdc++ code (in fact, this is the
|
256 |
|
|
reason STL requires any knowledge of the thread configuration).
|
257 |
|
|
</p><p>For implementing a container which does its own locking, it is
|
258 |
|
|
trivial to provide a wrapper class which obtains the lock (as
|
259 |
|
|
SGI suggests), performs the container operation, and then
|
260 |
|
|
releases the lock. This could be templatized <span class="emphasis"><em>to a certain
|
261 |
|
|
extent</em></span>, on the underlying container and/or a locking
|
262 |
|
|
mechanism. Trying to provide a catch-all general template
|
263 |
|
|
solution would probably be more trouble than it's worth.
|
264 |
|
|
</p><p>The library implementation may be configured to use the
|
265 |
|
|
high-speed caching memory allocator, which complicates thread
|
266 |
|
|
safety issues. For all details about how to globally override
|
267 |
|
|
this at application run-time
|
268 |
|
|
see <a class="link" href="using_macros.html" title="Macros">here</a>. Also
|
269 |
|
|
useful are details
|
270 |
|
|
on <a class="link" href="memory.html#std.util.memory.allocator" title="Allocators">allocator</a>
|
271 |
|
|
options and capabilities.
|
272 |
|
|
</p></div></div><div class="navfooter"><hr/><table width="100%" summary="Navigation footer"><tr><td align="left"><a accesskey="p" href="using_dynamic_or_shared.html">Prev</a> </td><td align="center"><a accesskey="u" href="using.html">Up</a></td><td align="right"> <a accesskey="n" href="using_exceptions.html">Next</a></td></tr><tr><td align="left" valign="top">Linking </td><td align="center"><a accesskey="h" href="../index.html">Home</a></td><td align="right" valign="top"> Exceptions</td></tr></table></div></body></html>
|