2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-08 11:12:23 +00:00

Compare commits

..

17 Commits

Author SHA1 Message Date
nobody
c8bd5fe1d8 This commit was manufactured by cvs2svn to create branch
'compiler_supported_error_messages'.

[SVN r13249]
2002-03-22 12:16:42 +00:00
William E. Kempf
2775a2a945 Updated <runtime-link> info in Jamfile
[SVN r13198]
2002-03-14 23:29:18 +00:00
William E. Kempf
c43c1febba Fixed bug in example in mutex.html
[SVN r13197]
2002-03-14 23:24:16 +00:00
William E. Kempf
ceb6471d57 Updated thread.html for new documentation style.
[SVN r13196]
2002-03-14 23:23:48 +00:00
William E. Kempf
b99cc044f3 Updated Jamfile
[SVN r13095]
2002-03-05 16:27:46 +00:00
Rene Rivera
d91429dcec Moved the <runtime-link> to the build request.
[SVN r13018]
2002-03-02 18:41:22 +00:00
William E. Kempf
b1d1f7d8f1 Jamfile modifications
[SVN r13001]
2002-03-01 23:10:11 +00:00
Dave Abrahams
86b608cf41 Updates to work on Linux
[SVN r12981]
2002-02-28 12:35:05 +00:00
Dave Abrahams
f263f75751 Killed bogus runtime-link specification
[SVN r12946]
2002-02-27 02:11:12 +00:00
William E. Kempf
24bec05b86 Added .cvsignore and updated Jam stuff
[SVN r12944]
2002-02-26 21:02:13 +00:00
William E. Kempf
ce1a5e9359 fixed missing } bug
[SVN r12903]
2002-02-22 18:32:08 +00:00
William E. Kempf
311525bc06 replaced <dll>thread_mon with $(THREADMON_DLL)
[SVN r12902]
2002-02-22 18:31:20 +00:00
William E. Kempf
ecdfd96529 fixed typename warnings
[SVN r12901]
2002-02-22 18:30:34 +00:00
William E. Kempf
5aab32bc1a More Jamfile changes.
[SVN r12857]
2002-02-18 23:04:25 +00:00
William E. Kempf
e152a1c6f2 Updated Jamfiles for new Boost.Build system
[SVN r12856]
2002-02-18 23:02:38 +00:00
Rene Rivera
e84fde78ec Updated the basic Jamfiles for the new Boost.Build changes.
[SVN r12798]
2002-02-14 04:08:20 +00:00
William E. Kempf
6ec4652bcf Updated thread documentation to use new templates.
[SVN r12785]
2002-02-11 23:13:04 +00:00
17 changed files with 1269 additions and 1266 deletions

2
build/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
bin*
*.pdb

View File

@@ -3,47 +3,68 @@
# in all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
#
# Boost.Threads build and test Jamfile
# Boost.Threads build Jamfile
#
# Declares the following targets:
# 1. libboost_thread, a static link library.
# 1a. On Win32, a dynamic link library libboost_threadmon,
# which must be used in conjunction with libboost_thread.
# 1a. On Win32 (when PTW32 is not defined), a dynamic link library
# boost_threadmon, which must be used in conjunction with
# libboost_thread. Note that this DLL *must* be used through static
# linking to the import library. Dynamic loading will cause undefined
# behavior.
# Additional configuration variables used:
# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
# library should be used instead of "native" threads. This feature is
# mostly used for testing and it's generally recommended you use the
# native threading libraries instead. PTW32 should be set to be a list
# of two strings, the first specifying the installation path of the
# pthreads-win32 library and the second specifying which library
# variant to link against (see the pthreads-win32 documentation).
# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
# declare the location of this subproject relative to the root
# Declare the location of this subproject relative to the root.
subproject libs/thread/build ;
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
SEARCH on <module@>threads.jam = $(BOOST_ROOT)/libs/thread/build ;
include <module@>threads.jam ;
#######################
# Conditionally declare the Boost.Threads dynamic link library boost_threadmon.
#
# Declare the Boost.Threads static link library.
#
# For Win32 we need to build a special DLL, libboost_threadmon, to handle
# TSS destruction.
if $(NT)
if $(NT) && ! $(PTW32)
{
if $(PTW32)
{
PTW32_REQUIREMENTS = <define>BOOST_HAS_PTHREADS <define>PtW32NoCatchWarn ;
}
else
{
dll libboost_threadmon : ../src/threadmon.cpp
# requirements
: <include>$(BOOST_ROOT)
<threading>multi
: debug release ;
}
dll boost_threadmon
: ../src/threadmon.cpp
: <include>$(BOOST_ROOT)
<threading>multi
: debug release <runtime-link>static/dynamic
;
}
# Base names of the source files for libboost_thread
#######################
# Declare the Boost.Threads static link library libboost_thread.
# Base names of the source files for libboost_thread.
CPP_SOURCES =
condition mutex recursive_mutex thread tss xtime once exceptions ;
lib libboost_thread : ../src/$(CPP_SOURCES).cpp
# requirements
lib boost_thread
: ../src/$(CPP_SOURCES).cpp
: <include>$(BOOST_ROOT)
$(PTW32_REQUIREMENTS)
<threading>multi
: debug release ;
<threading>multi
$(pthreads-win32)
: debug release <runtime-link>static/dynamic
;
#######################
# Stage the generated targets.
stage bin-stage
: <lib>boost_thread $(threadmon)
: <tag><runtime-link-static>"s"
<tag><debug>"d"
: debug release <runtime-link>static/dynamic
;

23
build/threads.jam Normal file
View File

@@ -0,0 +1,23 @@
# Do some OS-specific setup
threadmon = ;
pthreads-win32 = ;
if $(NT)
{
if $(PTW32)
{
local install-path = $(PTW32[1]) ;
local lib = $(PTW32[2]) ;
pthreads-win32 =
<define>BOOST_HAS_PTHREADS
<define>PtW32NoCatchWarn
<include>$(install-path)/pre-built/include
<library-file>$(install-path)/pre-built/lib/$(lib)
;
}
else
{
threadmon = <dll>../build/boost_threadmon ;
}
}

View File

@@ -1,97 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<meta name="keywords" content="threads, BTL, thread library, C++">
<title>Boost.Threads, Configuration Information</title>
</head>
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
<table summary="header" border="0" cellpadding="7" cellspacing="0"
width="100%">
<tr>
<td valign="top" width="300">
<h3><img src="../../../c++boost.gif" alt="C++ Boost" width=
"277" height="86"></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Configuration Information</h2>
</td>
</tr>
</table>
<hr>
<p><b>Boost.Threads</b> uses several configuration macros in <a href=
"../../config/config.htm">&lt;boost/config.hpp&gt;</a>. These macros
are documented here. Most of the macros are of interest only to
developers attempting to provide new implementations of <b>
Boost.Threads</b>. The one exception to this is BOOST_HAS_THREADS.</p>
<table summary="macros" cellspacing="10" width="100%">
<tr>
<td valign="top"><b>Macro</b> </td>
<td valign="top"><b>Meaning</b> </td>
</tr>
<tr>
<td valign="top">BOOST_HAS_THREADS</td>
<td valign="top">Indicates that threading support is available.
This means both that there is a platform specific
implementation for <b>Boost.Threads</b> and that threading
support has been enabled in a platform specific manner. For
instance, on the Win32 platform there&#39;s an implementation
for <b>Boost.Threads</b> but unless the program is compiled
against one of the multi-threading runtimes (often determined
by the compiler predefining the macro _MT) the
BOOST_HAS_THREADS macro remains undefined.</td>
</tr>
<tr>
<td valign="top">BOOST_HAS_WINTHREADS</td>
<td valign="top">Indicates that the platform has the Microsoft
Win32 threading libraries, and that they should be used to
implement <b>Boost.Threads</b>.</td>
</tr>
<tr>
<td valign="top">BOOST_HAS_PTHREADS</td>
<td valign="top">Indicates that the platform has the POSIX
pthreads libraries, and that they should be used to implement
<b>Boost.Threads</b>.</td>
</tr>
<tr>
<td valign="top">BOOST_HAS_FTIME</td>
<td valign="top">Indicates that the implementation should use
GetSystemTimeAsFileTime() and the FILETIME type to calculate
the current time. This is an implementation detail used by
boost::detail::getcurtime().</td>
</tr>
<tr>
<td valign="top">BOOST_HAS_GETTTIMEOFDAY</td>
<td valign="top">Indicates that the implementation should use
gettimeofday() to calculate the current time. This is an
implementation detail used by boost::detail::getcurtime().</td>
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->05 November, 2001<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p><i>&copy; Copyright <a href="mailto:williamkempf@hotmail.com">
William E. Kempf</a> 2001 all rights reserved.</i></p>
</body>
</html>

94
doc/configuration.html Normal file
View File

@@ -0,0 +1,94 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Threads - Configuration</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Configuration</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#lib-defined-public">Public Library Defined Macros</a></dt>
<dt><a href="#lib-defined-impl">Library Defined Implementation Macros</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p><b>Boost.Threads</b> uses several configuration macros in <a href="../../config/config.htm">&lt;boost/config.hpp&gt;</a>,
as well as configuration macros meant to be supplied by the application. These
macros are documented here.</p>
<h2><a name="lib-defined-public"></a>Public Library Defined Macros</h2>
<p>These macros are defined by <b>Boost.Threads</b> but are expected to be used by application
code.</p>
<table summary="public library defined macros" cellspacing="10" width="100%">
<tr>
<td><b>Macro</b></td>
<td><b>Meaning</b></td>
</tr>
<tr>
<td>BOOST_HAS_THREADS</td>
<td>Indicates that threading support is available. This means both that there
is a platform specific implementation for <b>Boost.Threads</b> and that
threading support has been enabled in a platform specific manner. For instance,
on the Win32 platform there&#39;s an implementation for <b>Boost.Threads</b>
but unless the program is compiled against one of the multi-threading runtimes
(often determined by the compiler predefining the macro _MT) the BOOST_HAS_THREADS
macro remains undefined.</td>
</tr>
</table>
<h2><a name="lib-defined-impl"></a>Library Defined Implementation Macros</h2>
<p>These macros are defined by <b>Boost.Threads</b> and are implementation details of interest
only to implementers.</p>
<table summary="library defined implementation macros" cellspacing="10" width="100%">
<tr>
<td><b>Macro</b></td>
<td><b>Meaning</b></td>
</tr>
<tr>
<td>BOOST_HAS_WINTHREADS</td>
<td>Indicates that the platform has the Microsoft Win32 threading libraries,
and that they should be used to implement <b>Boost.Threads</b>.</td>
</tr>
<tr>
<td>BOOST_HAS_PTHREADS</td>
<td>Indicates that the platform has the POSIX pthreads libraries, and that
they should be used to implement <b>Boost.Threads</b>.</td>
</tr>
<tr>
<td>BOOST_HAS_FTIME</td>
<td>Indicates that the implementation should use GetSystemTimeAsFileTime()
and the FILETIME type to calculate the current time. This is an implementation
detail used by boost::detail::getcurtime().</td>
</tr>
<tr>
<td>BOOST_HAS_GETTTIMEOFDAY</td>
<td>Indicates that the implementation should use gettimeofday() to calculate
the current time. This is an implementation detail used by boost::detail::getcurtime().</td>
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="mailto:wekempf@cox.net">William E. Kempf</a> 2001-2002.
All Rights Reserved.</i></p>
<p>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation. William E. Kempf
makes no representations about the suitability of this software for any purpose.
It is provided &quot;as is&quot; without express or implied warranty.</p>
</body>
</html>

View File

@@ -1,138 +1,157 @@
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<meta name="keywords" content="threads, BTL, thread library, C++">
<title>Boost.Threads, Index</title>
</head>
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
<table summary="header" border="0" cellpadding="7" cellspacing="0"
width="100%">
<tr>
<td valign="top" width="300">
<h3><img src="../../../c++boost.gif" alt="C++ Boost" width=
"277" height="86"></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Documentation Map</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<ul>
<li><a href="overview.html">Overview</a></li>
<li>
<a href="mutex_concept.html">Mutex Concepts</a>
<ul>
<li><a href="mutex_concept.html#Mutex">Mutex</a></li>
<li><a href="mutex_concept.html#TryMutex">TryMutex</a></li>
<li><a href="mutex_concept.html#TimedMutex">
TimedMutex</a></li>
</ul>
</li>
<li>
Mutex Classes
<ul>
<li><a href="mutex.html">mutex / try_mutex /
timed_mutex</a></li>
<li><a href="recursive_mutex.html">recursive_mutex /
recursive_try_mutex / recursive_timed_mutex</a></li>
</ul>
</li>
<li>
<a href="lock_concept.html">Lock Concepts</a>
<ul>
<li><a href="lock_concept.html#Lock">Lock</a></li>
<li><a href="lock_concept.html#ScopedLock">
ScopedLock</a></li>
<li><a href="lock_concept.html#ScopedTryLock">
ScopedTryLock</a></li>
<li><a href="lock_concept.html#ScopedTimedLock">
ScopedTimedLock</a></li>
</ul>
</li>
<li>
Lock Classes
<ul>
<li><a href="scoped_lock.html">scoped_lock</a></li>
<li><a href="scoped_try_lock.html">scoped_try_lock</a></li>
<li><a href="scoped_timed_lock.html">
scoped_timed_lock</a></li>
</ul>
</li>
<li>Class <a href="condition.html">condition</a></li>
<li>Class <a href="thread_specific_ptr.html">
thread_specific_ptr</a></li>
<li>Class <a href="thread.html">thread</a></li>
<li>Class <a href="thread_group.html">thread_group</a></li>
<li>Class <a href="xtime.html">xtime</a></li>
<li>Class <a href="lock_error.html">lock_error</a></li>
<li>Class <a href="thread_resource_error.html">
thread_resource_error</a></li>
<li>Routine <a href="call_once.html">call_once</a></li>
<li><a href="config.html">Configuration Information</a></li>
<li><a href="introduction.html">Introduction to design</a></li>
<li><a href="rationale.html">Rationale for design
decisions</a></li>
<li><a href="definitions.html">Definitions</a></li>
<li><a href="faq.html">Frequently Asked Questions</a></li>
<li><a href="bibliography.html">Bibliography</a></li>
<li><a href="acknowledgements.html">Acknowledgements</a></li>
</ul>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->05 November, 2001<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p>&copy; <i>Copyright <a href="mailto:williamkempf@hotmail.com">
William E. Kempf</a> 2001</i></p>
<p>Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation. William E. Kempf makes no representations
about the suitability of this software for any purpose. It is provided
&quot;as is&quot; without express or implied warranty.</p>
</body>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Threads</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Index</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="overview.html">Overview</a></dt>
<dt><a href="mutex_concept.html">Mutex Concepts</a></dt>
<dl class="index">
<dt><a href="mutex_concept.html#Mutex">Mutex</a></dt>
<dt><a href="mutex_concept.html#TryMutex">TryMutex</a></dt>
<dt><a href="mutex_concept.html#TimedMutex">TimedMutex</a></dt>
</dl>
<dt><a href="lock_concept.html">Lock Concepts</a></dt>
<dl class="index">
<dt><a href="lock_concept.html#Lock">Lock</a></dt>
<dt><a href="lock_concept.html#ScopedLock">ScopedLock</a></dt>
<dt><a href="lock_concept.html#ScopedTryLock">ScopedTryLock</a></dt>
<dt><a href="lock_concept.html#ScopedTimedLock">ScopedTimedLock</a></dt>
</dl>
<dt>Reference</dt>
<dl class="index">
<dt><a href="mutex.html">&lt;boost/condition.hpp&gt;</a></dt>
<dl class="index">
<dt><a href="header.html#classes">Classes</a></dt>
<dl class="index">
<dt><a href="header.html#mutex">condition</a></dt>
</dl>
</dl>
</dl>
<dl class="index">
<dt><a href="mutex.html">&lt;boost/mutex.hpp&gt;</a></dt>
<dl class="index">
<dt><a href="header.html#classes">Classes</a></dt>
<dl class="index">
<dt><a href="header.html#mutex">mutex</a></dt>
</dl>
<dl class="index">
<dt><a href="header.html#try_mutex">try_mutex</a></dt>
</dl>
<dl class="index">
<dt><a href="header.html#timed_mutex">timed_mutex</a></dt>
</dl>
</dl>
<dt><a href="mutex.html">&lt;boost/recursive_mutex.hpp&gt;</a></dt>
<dl class="index">
<dt><a href="header.html#classes">Classes</a></dt>
<dl class="index">
<dt><a href="header.html#recursive_mutex">recursive_mutex</a></dt>
</dl>
<dl class="index">
<dt><a href="header.html#recursive_try_mutex">recursive_try_mutex</a></dt>
</dl>
<dl class="index">
<dt><a href="header.html#recursive_timed_mutex">recursive_timed_mutex</a></dt>
</dl>
</dl>
</dl>
<dl class="index">
<dt><a href="mutex.html">&lt;boost/tss.hpp&gt;</a></dt>
<dl class="index">
<dt><a href="header.html#classes">Classes</a></dt>
<dl class="index">
<dt><a href="header.html#mutex">thread_specific_ptr</a></dt>
</dl>
</dl>
</dl>
<dl class="index">
<dt><a href="mutex.html">&lt;boost/thread.hpp&gt;</a></dt>
<dl class="index">
<dt><a href="header.html#classes">Classes</a></dt>
<dl class="index">
<dt><a href="header.html#mutex">thread</a></dt>
</dl>
<dl class="index">
<dt><a href="header.html#mutex">thread_group</a></dt>
</dl>
</dl>
</dl>
<dl class="index">
<dt><a href="xtime.html">&lt;boost/xtime.hpp&gt;</a></dt>
<dl class="index">
<dt><a href="header.html#classes">Classes</a></dt>
<dl class="index">
<dt><a href="header.html#mutex">xtime</a></dt>
</dl>
</dl>
</dl>
<dl class="index">
<dt><a href="header.html">{{header}}</a></dt>
<dl class="index">
<dt><a href="header.html#macros">Macros</a></dt>
<dl class="index">
<dt><a href="header.html#macro-spec">{{macro name}}</a></dt>
</dl>
<dt><a href="header.html#values">Values</a></dt>
<dl class="index">
<dt><a href="header.html#value-spec">{{value name}}</a></dt>
</dl>
<dt><a href="header.html#types">Types</a></dt>
<dl class="index">
<dt><a href="header.html#value-spec">{{type name}}</a></dt>
</dl>
<dt><a href="header.html#classes">Classes</a></dt>
<dl class="index">
<dt><a href="header.html#value-spec">{{class name}}</a></dt>
</dl>
<dt><a href="header.html#functions">Functions</a></dt>
<dl class="index">
<dt><a href="header.html#value-spec">{{function name}}</a></dt>
</dl>
<dt><a href="header.html#objects">Objects</a></dt>
<dl class="index">
<dt><a href="header.html#value-spec">{{object name}}</a></dt>
</dl>
</dl>
</dl>
<dt><a href="configuration.html">Configuration Information</a></dt>
<dt><a href="introduction.html">Introduction to Design</a></dt>
<dt><a href="rationale.html">Rationale</a></dt>
<dt><a href="definitions.html">Definitions</a></dt>
<dt><a href="faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="bibliography.html">Bibliography</a></dt>
<dt><a href="acknowledgments.html">Acknowledgments</a></dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="mailto:wekempf@cox.net">William E. Kempf</a> 2001-2002.
All Rights Reserved.</i></p>
<p>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation. William E. Kempf
makes no representations about the suitability of this software for any purpose.
It is provided &quot;as is&quot; without express or implied warranty.</p>
</body>
</html>

View File

@@ -1,194 +1,160 @@
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<meta name="keywords" content="threads, BTL, thread library, C++">
<title>Boost.Threads, Introduction</title>
</head>
<body bgcolor="#ffffff" link="#0000ff" vlink="#800080">
<table summary="header" border="0" cellpadding="7" cellspacing="0"
width="100%">
<tr>
<td valign="top" width="300">
<h3><img height="86" alt="C++ Boost" src=
"../../../c++boost.gif" width="277"></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Introduction</h2>
</td>
</tr>
</table>
<hr>
<h3>Motivation</h3>
<p>With client/server and three-tier architectures becoming common
place in today&#39;s world, it&#39;s becoming increasingly important
for programs to be able to handle parallel processing. Modern day
operating systems usually provide some support for this through native
thread APIs. Unfortunately, writing portable code that makes use of
parallel processing in C++ is made very difficult by a lack of a
standard interface for these native APIs. Further, these APIs are
almost universally C APIs and fail to take advantage of C++&#39;s
strengths, or to address C++&#39;s issues.</p>
<p>The <b>Boost.Threads</b> library is an attempt to define a portable
interface for writing parallel processes in C++.</p>
<h3>Goals</h3>
<p>The <b>Boost.Threads</b> library has several goals that should help
to set it apart from other solutions. These goals are listed in order
of precedence with full descriptions below.</p>
<ul>
<li>
<b>Portability</b>
<p><b>Boost.Threads</b> was designed to be highly portable. The
goal is for the interface to be easily implemented on any
platform that supports threads, and possibly even on platforms
without native thread support.</p>
</li>
<li>
<b>Safety</b>
<p><b>Boost.Threads</b> was designed to be as safe as possible.
Writing <a href="definitions.html#Thread-safe">thread-safe</a>
code is very difficult and successful libraries must strive to
insulate the programmer from dangerous constructs as much as
possible. This is accomplished in several ways:</p>
<ul>
<li>
<p align="left">C++ language features are used make
correct usage easy (if possible, the default) and
error-prone impossible or at least more difficult. For
example, see the <a href="mutex_concept.html">Mutex</a>
and <a href="lock_concept.html">Lock</a> designs, and
how note how they interact.</p>
</li>
<li>
<p align="left">Certain traditional concurrent
programming features are considered so error-prone that
they are not provided at all. For example, see the <a
href="rationale.html#Events">Events Not Provided</a>
rationale.</p>
</li>
<li>
<p align="left">Dangerous features, or features which
may be misused, are identified as such in the
documentation to make users aware of potential
pitfalls.</p>
</li>
</ul>
</li>
<li>
<b>Flexibility</b>
<p><b>Boost.Threads</b> was designed to be flexible. This goal
is often at odds with <i>safety</i>. When functionality might
be compromised by the desire to keep the interface safe, <b>
Boost.Threads</b> has been designed to provide the
functionality, but to make it&#39;s use prohibitive for general
use.</p>
</li>
<li>
<b>Efficiency</b>
<p><b>Boost.Threads</b> was designed to be as efficient as
possible. When building a library on top of another library
there is always a danger that the result will be so much slower
than the &quot;native&quot; API that programmers are inclined
to ignore the higher level API. <b>Boost.Threads</b> was
designed to minimize the chances of this occurring. The
interfaces have been crafted to allow an implementation the
greatest chance of being as efficient as possible. This goal is
often at odds with the goal for <i>safety</i>. Every effort was
made to ensure efficient implementations, but when in conflict
<i>safety</i> has always taken precedence.</p>
</li>
</ul>
<h3>Iterative Phases</h3>
<p>Another goal of <b>Boost.Threads</b> was to take a dynamic,
iterative approach in its development. The computing industry is still
exploring the concepts of parallel programming. Most thread libraries
supply only simple primitive concepts for thread synchronization. These
concepts are very simple, but they are very difficult to use safely or
to provide formal proofs for constructs built on top of them. Until
recently, these primitives were &quot;state of the art&quot; and the
only concepts available to programmers. Recently there has been a lot
of research in other concepts, such as in &quot;Communicating
Sequential Processes.&quot; <b>Boost.Threads</b> was designed in
iterative steps, providing the building blocks necessary for the next
step, and giving the researcher the tools necessary to explore new
concepts in a portable manner.</p>
<p>Given the goal of following a dynamic, iterative approach <b>
Boost.Threads</b> shall go through several growth cycles. Each phase in
its development shall be roughly documented here.</p>
<h4>Phase 1, Synchronization Primitives</h4>
<p>Boost is all about providing high quality libraries with
implementations for many platforms. Unfortunately, there&#39;s a big
problem faced by developers wishing to supply such high quality
libraries, namely thread-safety. The C++ standard doesn&#39;t address
threads at all, but real world programs often make use of native
threading support. A portable library that doesn&#39;t address the
issue of thread-safety is there for not much help to a programmer who
wants to use the library in his multi-threaded application. So
there&#39;s a very great need for portable primitives that will allow
the library developer to create <a href="definitions.html#Thread-safe">
thread-safe</a> implementations. This need far out weighs the need for
portable methods to create and manage threads.</p>
<p>Because of this need, the first phase of <b>Boost.Threads</b>
focuses solely on providing portable primitive concepts for thread
synchronization. Types provided in this phase include the <a href="mutex.html">
mutex/try_mutex/timed_mutex</a>, <a href="recursive_mutex.html">
recursive_mutex/recursive_try_mutex/recursive_timed_mutex</a>, <a href=
"scoped_lock.html">scoped_lock</a>, <a href="scoped_try_lock.html">
scoped_try_lock</a>, <a href="scoped_timed_lock.html">
scoped_timed_lock</a> and <a href="lock_error.html">lock_error</a>.
These are considered the &quot;core&quot; synchronization primitives,
though there are others that will be added in later phases.</p>
<h4>Phase 2, Thread Management and Thread Specific Storage</h4>
<p>This phase addresses the creation and management of threads and
provides a mechanism for thread specific storage (data associated with
a thread instance). Thread management is a tricky issue in C++, so this
phase addresses only the basic needs of multi-threaded program. Later
phases are likely to add additional functionality in this area. This
phase of <b>Boost.Threads</b> adds the <a href="thread.html">thread</a>
and <a href="thread_specific_ptr.html">thread_specific_ptr</a> types.
With these additions the <b>Boost.Threads</b> library can be considered
minimal but complete.</p>
<h4>The Next Phase</h4>
<p>The next phase will address more advanced synchronization concepts,
such as read/write mutexes and barriers.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->05 November, 2001<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p><i>&copy; Copyright <a href="mailto:williamkempf@hotmail.com">
William E. Kempf</a> 2001 all rights reserved.</i></p>
</body>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Threads - Overview</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Introduction to Design</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#motivation">Motivation</a></dt>
<dt><a href="#goals">Goals</a></dt>
<dt><a href="#phases">Iterative Phases</a></dt>
<dl class="page-index">
<dt><a href="#phase1">Phase 1, Synchronization Primitives</a></dt>
<dt><a href="#phase2">Phase 2, Thread Management and Thread Specific Storage</a></dt>
<dt><a href="#next-phase">The Next Phase</a></dt>
</dl>
</dl>
<h2><a name="motivation"></a>Motivation</h2>
<p>With client/server and three-tier architectures becoming common place in today&#39;s
world, it&#39;s becoming increasingly important for programs to be able to handle
parallel processing. Modern day operating systems usually provide some support
for this through native thread APIs. Unfortunately, writing portable code that
makes use of parallel processing in C++ is made very difficult by a lack of
a standard interface for these native APIs. Further, these APIs are almost universally
C APIs and fail to take advantage of C++&#39;s strengths, or to address C++&#39;s
issues.</p>
<p>The <b>Boost.Threads</b> library is an attempt to define a portable interface
for writing parallel processes in C++.</p>
<h2><a name="goals"></a>Goals</h2>
<p>The <b>Boost.Threads</b> library has several goals that should help to set
it apart from other solutions. These goals are listed in order of precedence
with full descriptions below.</p>
<ul>
<li> <b>Portability</b>
<p><b>Boost.Threads</b> was designed to be highly portable. The goal is for
the interface to be easily implemented on any platform that supports threads,
and possibly even on platforms without native thread support.</p>
</li>
<li> <b>Safety</b>
<p><b>Boost.Threads</b> was designed to be as safe as possible. Writing <a href="definitions.html#Thread-safe">thread-safe</a>
code is very difficult and successful libraries must strive to insulate
the programmer from dangerous constructs as much as possible. This is accomplished
in several ways:</p>
<ul>
<li>
<p align="left">C++ language features are used make correct usage easy
(if possible, the default) and error-prone impossible or at least more
difficult. For example, see the <a href="mutex_concept.html">Mutex</a>
and <a href="lock_concept.html">Lock</a> designs, and how note how they
interact.</p>
</li>
<li>
<p align="left">Certain traditional concurrent programming features are
considered so error-prone that they are not provided at all. For example,
see the <a
href="rationale.html#Events">Events Not Provided</a> rationale.</p>
</li>
<li>
<p align="left">Dangerous features, or features which may be misused,
are identified as such in the documentation to make users aware of potential
pitfalls.</p>
</li>
</ul>
</li>
<li> <b>Flexibility</b>
<p><b>Boost.Threads</b> was designed to be flexible. This goal is often at
odds with <i>safety</i>. When functionality might be compromised by the
desire to keep the interface safe, <b> Boost.Threads</b> has been designed
to provide the functionality, but to make it&#39;s use prohibitive for general
use.</p>
</li>
<li> <b>Efficiency</b>
<p><b>Boost.Threads</b> was designed to be as efficient as possible. When
building a library on top of another library there is always a danger that
the result will be so much slower than the &quot;native&quot; API that programmers
are inclined to ignore the higher level API. <b>Boost.Threads</b> was designed
to minimize the chances of this occurring. The interfaces have been crafted
to allow an implementation the greatest chance of being as efficient as
possible. This goal is often at odds with the goal for <i>safety</i>. Every
effort was made to ensure efficient implementations, but when in conflict
<i>safety</i> has always taken precedence.</p>
</li>
</ul>
<h2><a name="phases"></a>Iterative Phases</h2>
<p>Another goal of <b>Boost.Threads</b> was to take a dynamic, iterative approach
in its development. The computing industry is still exploring the concepts of
parallel programming. Most thread libraries supply only simple primitive concepts
for thread synchronization. These concepts are very simple, but they are very
difficult to use safely or to provide formal proofs for constructs built on
top of them. Until recently, these primitives were &quot;state of the art&quot;
and the only concepts available to programmers. Recently there has been a lot
of research in other concepts, such as in &quot;Communicating Sequential Processes.&quot;
<b>Boost.Threads</b> was designed in iterative steps, providing the building
blocks necessary for the next step, and giving the researcher the tools necessary
to explore new concepts in a portable manner.</p>
<p>Given the goal of following a dynamic, iterative approach <b> Boost.Threads</b>
shall go through several growth cycles. Each phase in its development shall
be roughly documented here.</p>
<h3><a name="phase1"></a>Phase 1, Synchronization Primitives</h3>
<p>Boost is all about providing high quality libraries with implementations for
many platforms. Unfortunately, there&#39;s a big problem faced by developers
wishing to supply such high quality libraries, namely thread-safety. The C++
standard doesn&#39;t address threads at all, but real world programs often make
use of native threading support. A portable library that doesn&#39;t address
the issue of thread-safety is there for not much help to a programmer who wants
to use the library in his multi-threaded application. So there&#39;s a very
great need for portable primitives that will allow the library developer to
create <a href="definitions.html#Thread-safe"> thread-safe</a> implementations.
This need far out weighs the need for portable methods to create and manage
threads.</p>
<p>Because of this need, the first phase of <b>Boost.Threads</b> focuses solely
on providing portable primitive concepts for thread synchronization. Types provided
in this phase include the <a href="mutex.html"> mutex/try_mutex/timed_mutex</a>,
<a href="recursive_mutex.html"> recursive_mutex/recursive_try_mutex/recursive_timed_mutex</a>,
<a href=
"scoped_lock.html">scoped_lock</a>, <a href="scoped_try_lock.html"> scoped_try_lock</a>,
<a href="scoped_timed_lock.html"> scoped_timed_lock</a> and <a href="lock_error.html">lock_error</a>.
These are considered the &quot;core&quot; synchronization primitives, though
there are others that will be added in later phases.</p>
<h3><a name="phase2"></a>Phase 2, Thread Management and Thread Specific Storage</h3>
<p>This phase addresses the creation and management of threads and provides a
mechanism for thread specific storage (data associated with a thread instance).
Thread management is a tricky issue in C++, so this phase addresses only the
basic needs of multi-threaded program. Later phases are likely to add additional
functionality in this area. This phase of <b>Boost.Threads</b> adds the <a href="thread.html">thread</a>
and <a href="thread_specific_ptr.html">thread_specific_ptr</a> types. With these
additions the <b>Boost.Threads</b> library can be considered minimal but complete.</p>
<h3><a name="next-phase"></a>The Next Phase</h3>
<p>The next phase will address more advanced synchronization concepts, such as
read/write mutexes and barriers.</p>
<hr>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="mailto:wekempf@cox.net">William E. Kempf</a> 2001-2002.
All Rights Reserved.</i></p>
<p>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation. William E. Kempf
makes no representations about the suitability of this software for any purpose.
It is provided &quot;as is&quot; without express or implied warranty.</p>
</body>
</html>

View File

@@ -320,7 +320,7 @@ private:
counter c;
void change_count(void*)
void change_count()
{
int i = c.increment();
boost::mutex::scoped_lock scoped_lock(io_mutex);
@@ -332,7 +332,7 @@ int main(int, char*[])
const int num_threads = 4;
boost::thread_group thrds;
for (int i=0; i &lt; num_threads; ++i)
thrds.create_thread(&amp;change_count, 0);
thrds.create_thread(&amp;change_count);
thrds.join_all();

View File

@@ -1,224 +1,174 @@
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost.Threads Overview</title>
</head>
<body>
<table summary="header" border="0" cellpadding="7" cellspacing="0"
width="100%">
<tr>
<td valign="top" width="300">
<h3><img height="86" alt="C++ Boost" src=
"../../../c++boost.gif" width="277"></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Overview</h2>
</td>
</tr>
</table>
<p><a href="#Introduction">Introduction</a><br>
<a href="#Dangers">Dangers</a><br>
<a href="#Library">C++ Standard Library usage</a><br>
<a href="#Common">Common requirements</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>Boost.Threads allows C++ programs to execute as multiple,
asynchronous, independent, threads-of-execution. Each thread has its
own machine state including program instruction counter and registers.
Programs which execute as multiple threads are called multi-threaded
programs to distinguish them from traditional single-threaded programs.
<a href="definitions.html">Definitions</a> gives a more complete
description of the multi-threading execution environment.</p>
<p>Multi-threading provides several advantages:</p>
<ul>
<li>Programs which would otherwise block waiting for some external
event can continue to respond if the blocking operation is placed
in a separate thread. Multi-threading is usually an absolute
requirement for these programs.</li>
</ul>
<ul>
<li>Well-designed multi-threaded programs may execute faster than
single-threaded programs, particularly on multi-processor hardware.
Note, however, that poorly-designed multi-threaded programs are
often slower that single-threaded programs.</li>
</ul>
<ul>
<li>Some program designs may be easier to formulate using a
multi-threaded approach. After all, the real world is
asynchronous!</li>
</ul>
<h2><a name="Dangers">Dangers</a></h2>
<p>Beyond the errors which can occur in single-threaded programs,
multi-threaded programs are subject to additional errors:</p>
<ul>
<li><a href="definitions.html#Race condition">Race
conditions</a>.</li>
<li><a href="definitions.html#Deadlock">Deadlock</a> (sometimes
called &quot;deadly embrace&quot;)</li>
<li><a href="definitions.html#Priority failure">Priority
failures</a> (priority inversion, infinite overtaking, starvation,
etc.)</li>
</ul>
<p>Every multi-threaded program must be designed carefully to avoid
race conditions and deadlock. These aren&#39;t rare or exotic failures
- they are virtually guaranteed to occur unless multi-threaded code is
designed to avoid them. Priority failures are somewhat less common, but
are none-the-less serious.</p>
<p>The <a href="introduction.html">Boost.Threads design</a> attempts to
minimize these errors, but they will still occur unless the programmer
proactively designs to avoid them.</p>
<h3>Testing and debugging considerations</h3>
<p>Multi-threaded programs are non-deterministic. In other words, the
same program with the same input data may follow different execution
paths each time it is invoked. That can make testing and debugging a
nightmare:</p>
<ul>
<li>Failures are often not repeatable.</li>
<li>Probe effect causes debuggers to produce very different results
from non-debug uses.</li>
<li>Debuggers require special support to show thread state.</li>
<li>Tests on a single processor system may give no indication of
serious errors which would appear on multiprocessor systems, and
visa versa. Thus test cases should include a varying number of
processors.</li>
<li>For programs which create a varying number of threads according
to workload, tests which don&#39;t span the full range of
possibilities may miss serious errors.</li>
</ul>
<h3>Getting a head start</h3>
<p>Although it might appear that multi-threaded programs are inherently
unreliable, many reliable multi-threaded programs do exist.
Multi-threading techniques are known which lead to reliable
programs.</p>
<p>Design patterns for reliable multi-threaded programs, including the
important <i>monitor</i> pattern, are presented in <cite>
Pattern-Oriented Software Architecture Volume 2 - Patterns for
Concurrent and Networked Objects</cite> [<a href=
"bibliography.html#Schmidt-00">Schmidt 00</a>]. Many important
multi-threading programming considerations (independent of threading
library) are discussed in <cite>Programming with POSIX Threads</cite>
[<a href="bibliography.html#Butenhof-97">Butenhof 97</a>].</p>
<p>Doing some reading before attempting multi-threaded designs will give
you a head start toward reliable multi-threaded programs.</p>
<h2><a name="Library">C++ Standard Library usage in multi-threaded
programs</a></h2>
<h3>Runtime libraries</h3>
<p><b>Warning:</b> Multi-threaded programs such as those using <b>
Boost.Threads</b> must link to <a href="definitions.html#Thread-safe">
thread-safe</a> versions of all runtime libraries used by the program,
including the runtime library for the C++ Standard Library. Otherwise
<a href="definitions.html#Race condition">race conditions</a> will
occur when multiple threads simultaneously execute runtime library
functions for <i>new</i>, <i>delete</i>, or other language features
which imply shared state.</p>
<h3>Potentially non-thread-safe functions</h3>
<p>Certain C++ Standard Library functions inherited from C are
particular problems because they hold internal state between calls:</p>
<ul>
<li>rand</li>
<li>strtok</li>
<li>asctime</li>
<li>ctime</li>
<li>gmtime</li>
<li>localtime</li>
</ul>
<p>It is possible to write thread-safe implementations of these by
using <a href="thread_specific_ptr.html">thread-specific storage</a>,
and several C++ compiler vendors do just that. The technique is
well-know and is explained in [<a href=
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Threads - Overview</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Overview</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#dangers">Dangers</a></dt>
<dl class="index">
<dt><a href="#testing-debugging">Testing and debugging considerations</a></dt>
<dt><a href="#head-start">Getting a head start</a></dt>
</dl>
<dt><a href="#library">C++ Standard Library usage in multi-threaded programs</a></dt>
<dl class="index">
<dt><a href="#runtime-libraries">Runtime libraries</a></dt>
<dt><a href="#non-thread-safe-functions">Potentially non-thread-safe functions</a></dt>
</dl>
<dt><a href="#common-requirements">Common requirements for all Boost.Threads components</a></dt>
<dl class="index">
<dt><a href="#exceptions">Exceptions</a></dt>
<dt><a href="#non-copyable">NonCopyable requirement</a></dt>
</dl>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>Boost.Threads allows C++ programs to execute as multiple, asynchronous, independent,
threads-of-execution. Each thread has its own machine state including program
instruction counter and registers. Programs which execute as multiple threads
are called multi-threaded programs to distinguish them from traditional single-threaded
programs. <a href="definitions.html">Definitions</a> gives a more complete description
of the multi-threading execution environment.</p>
<p>Multi-threading provides several advantages:</p>
<ul>
<li>Programs which would otherwise block waiting for some external event can
continue to respond if the blocking operation is placed in a separate thread.
Multi-threading is usually an absolute requirement for these programs.</li>
</ul>
<ul>
<li>Well-designed multi-threaded programs may execute faster than single-threaded
programs, particularly on multi-processor hardware. Note, however, that poorly-designed
multi-threaded programs are often slower that single-threaded programs.</li>
</ul>
<ul>
<li>Some program designs may be easier to formulate using a multi-threaded approach.
After all, the real world is asynchronous!</li>
</ul>
<h2><a name="dangers"></a>Dangers</h2>
<p>Beyond the errors which can occur in single-threaded programs, multi-threaded
programs are subject to additional errors:</p>
<ul>
<li><a href="definitions.html#Race condition">Race conditions</a>.</li>
<li><a href="definitions.html#Deadlock">Deadlock</a> (sometimes called &quot;deadly
embrace&quot;)</li>
<li><a href="definitions.html#Priority failure">Priority failures</a> (priority
inversion, infinite overtaking, starvation, etc.)</li>
</ul>
<p>Every multi-threaded program must be designed carefully to avoid race conditions
and deadlock. These aren&#39;t rare or exotic failures - they are virtually
guaranteed to occur unless multi-threaded code is designed to avoid them. Priority
failures are somewhat less common, but are none-the-less serious.</p>
<p>The <a href="introduction.html">Boost.Threads design</a> attempts to minimize
these errors, but they will still occur unless the programmer proactively designs
to avoid them.</p>
<h3><a name="testing-debugging"></a>Testing and debugging considerations</h3>
<p>Multi-threaded programs are non-deterministic. In other words, the same program
with the same input data may follow different execution paths each time it is
invoked. That can make testing and debugging a nightmare:</p>
<ul>
<li>Failures are often not repeatable.</li>
<li>Probe effect causes debuggers to produce very different results from non-debug
uses.</li>
<li>Debuggers require special support to show thread state.</li>
<li>Tests on a single processor system may give no indication of serious errors
which would appear on multiprocessor systems, and visa versa. Thus test cases
should include a varying number of processors.</li>
<li>For programs which create a varying number of threads according to workload,
tests which don&#39;t span the full range of possibilities may miss serious
errors.</li>
</ul>
<h3><a name="head-start"></a>Getting a head start</h3>
<p>Although it might appear that multi-threaded programs are inherently unreliable,
many reliable multi-threaded programs do exist. Multi-threading techniques are
known which lead to reliable programs.</p>
<p>Design patterns for reliable multi-threaded programs, including the important
<i>monitor</i> pattern, are presented in <cite> Pattern-Oriented Software Architecture
Volume 2 - Patterns for Concurrent and Networked Objects</cite> [<a href=
"bibliography.html#Schmidt-00">Schmidt 00</a>]. Many important multi-threading
programming considerations (independent of threading library) are discussed
in <cite>Programming with POSIX Threads</cite> [<a href="bibliography.html#Butenhof-97">Butenhof
97</a>].</p>
<p>Doing some reading before attempting multi-threaded designs will give you a
head start toward reliable multi-threaded programs.</p>
<h2><a name="library"></a>C++ Standard Library usage in multi-threaded programs</h2>
<h3><a name="runtime-libraries"></a>Runtime libraries</h3>
<p><b>Warning:</b> Multi-threaded programs such as those using <b> Boost.Threads</b>
must link to <a href="definitions.html#Thread-safe"> thread-safe</a> versions
of all runtime libraries used by the program, including the runtime library
for the C++ Standard Library. Otherwise <a href="definitions.html#Race condition">race
conditions</a> will occur when multiple threads simultaneously execute runtime
library functions for <i>new</i>, <i>delete</i>, or other language features
which imply shared state.</p>
<h3><a name="non-thread-safe-functions"></a>Potentially non-thread-safe functions</h3>
<p>Certain C++ Standard Library functions inherited from C are particular problems
because they hold internal state between calls:</p>
<ul>
<li>rand</li>
<li>strtok</li>
<li>asctime</li>
<li>ctime</li>
<li>gmtime</li>
<li>localtime</li>
</ul>
<p>It is possible to write thread-safe implementations of these by using <a href="thread_specific_ptr.html">thread-specific
storage</a>, and several C++ compiler vendors do just that. The technique is
well-know and is explained in [<a href=
"bibliography.html#Butenhof-97">Buttenhof-97</a>].</p>
<p>But at least one vendor (HP-UX) does not provide thread-safe
implementations of the above functions in their otherwise thread-safe
runtime library. Instead they provide replacement functions with
different names and arguments.</p>
<p><b>Recommendation:</b> For the most portable, yet thread-safe code,
use Boost replacements for the problem functions. See the <a href=
<p>But at least one vendor (HP-UX) does not provide thread-safe implementations
of the above functions in their otherwise thread-safe runtime library. Instead
they provide replacement functions with different names and arguments.</p>
<p><b>Recommendation:</b> For the most portable, yet thread-safe code, use Boost
replacements for the problem functions. See the <a href=
"../../random/index.html">Boost Random Number Library</a> and <a href=
"../../tokenizer/index.htm">Boost Tokenizer Library</a>.</p>
<h2><a name="Common">Common</a> requirements for all Boost.Threads
components</h2>
<h3>Exceptions</h3>
<p><b>Boost.Threads</b> destructors never throw exceptions. Unless
otherwise specified, other <b>Boost.Threads</b> functions that do not
have an exception-specification may throw implementation-defined
exceptions.</p>
<p>In particular, <b>Boost.Threads</b> reports failure to allocate
storage by throwing an exception of type std::bad_alloc, or a class
derived from std::bad_alloc, failure to obtain thread resources other
than memory by throwing an exception of type <a href=
"thread_resource_error.html">boost::thread_resource_error</a>, and
certain lock related failures by throwing an exception of type <a href=
<h2><a name="common-requirements"></a>Common requirements for all Boost.Threads components</h2>
<h3><a name="exceptions"></a>Exceptions</h3>
<p><b>Boost.Threads</b> destructors never throw exceptions. Unless otherwise specified,
other <b>Boost.Threads</b> functions that do not have an exception-specification
may throw implementation-defined exceptions.</p>
<p>In particular, <b>Boost.Threads</b> reports failure to allocate storage by
throwing an exception of type std::bad_alloc, or a class derived from std::bad_alloc,
failure to obtain thread resources other than memory by throwing an exception
of type <a href=
"thread_resource_error.html">boost::thread_resource_error</a>, and certain
lock related failures by throwing an exception of type <a href=
"lock_error.html">boost::lock_error</a></p>
<p><b>Rationale:</b> Follows the C++ Standard Library practice of
allowing all functions except destructors or other specified functions
to throw exceptions on errors.</p>
<h3><a name="NonCopyable">NonCopyable</a> requirement</h3>
<p><b>Boost.Threads</b> classes documented as meeting the NonCopyable
requirement disallow copy construction and copy assignment. For the
sake of exposition, the synopsis of such classes show private
derivation from <a href="../../utility/utility.htm">
boost::noncopyable</a>. Users should not depend on this derivation,
however, as implementations are free to meet the NonCopyable
requirement in other ways.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->05 November, 2001<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p>&copy; Copyright 2001 Beman Dawes</p>
</body>
<p><b>Rationale:</b> Follows the C++ Standard Library practice of allowing all
functions except destructors or other specified functions to throw exceptions
on errors.</p>
<h3><a name="non-copyable"></a>NonCopyable requirement</h3>
<p><b>Boost.Threads</b> classes documented as meeting the NonCopyable requirement
disallow copy construction and copy assignment. For the sake of exposition,
the synopsis of such classes show private derivation from <a href="../../utility/utility.htm">
boost::noncopyable</a>. Users should not depend on this derivation, however,
as implementations are free to meet the NonCopyable requirement in other ways.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="mailto:wekempf@cox.net">William E. Kempf</a> 2001-2002.
All Rights Reserved.</i></p>
<p>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation. William E. Kempf
makes no representations about the suitability of this software for any purpose.
It is provided &quot;as is&quot; without express or implied warranty.</p>
</body>
</html>

View File

@@ -1,194 +1,155 @@
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<meta name="keywords" content="threads, BTL, thread library, C++">
<title>Boost.Threads, rationale</title>
</head>
<body bgcolor="#ffffff" link="#0000ff" vlink="#800080">
<table summary="header" border="0" cellpadding="7" cellspacing="0"
width="100%">
<tr>
<td valign="top" width="300">
<h3><img height="86" alt="C++ Boost" src=
"../../../c++boost.gif" width="277"></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Rationale</h2>
</td>
</tr>
</table>
<hr>
<p>This page explains the rationale behind various design decisions in
the <b>Boost.Threads</b> library. Having the rationale documented here
should explain how we arrived at the current design as well as prevent
future rehashing of discussions and thought processes that have already
occurred. It can also give users a lot of insight into the design
process required for this library.</p>
<h2><a name="library">Rationale for the Creation of
Boost.Threads</a></h2>
<p>Processes often have a degree of &quot;potential parallelism&quot;
and it can often be more intuitive to design systems with this in mind.
Further, these parallel processes can result in more responsive
programs. The benefits for multi-threaded programming are quite well
known to most modern programmers, yet the C++ language doesn&#39;t
directly support this concept.</p>
<p>Many platforms support multi-threaded programming despite the fact
that the language doesn&#39;t support it. They do this through external
libraries, which are, unfortunately, platform specific. POSIX has tried
to address this problem through the standardization of a
&quot;pthread&quot; library. However, this is a standard only on POSIX
platforms, so its portability is limited.</p>
<p>Another problem with POSIX and other platform specific thread
libraries is that they are almost universally C based libraries. This
leaves several C++ specific issues unresolved, such as what happens
when an exception is thrown in a thread. Further, there are some C++
concepts, such as destructors, that can make usage much easier than
what&#39;s available in a C library.</p>
<p>What&#39;s truly needed is C++ language support for threads.
However, the C++ standards committee needs existing practice or a good
proposal as a starting point for adding this to the standard.</p>
<p>The Boost.Threads library was developed to provide a C++ developer
with a portable interface for writing multi-threaded programs on
numerous platforms. There&#39;s a hope that the library can be the
basis for a more detailed proposal for the C++ standards committee to
consider for inclusion in the next C++ standard.</p>
<h2><a name="primitives">Rationale for the Low Level Primitives
Supported in Boost.Threads</a></h2>
<p>The Boost.Threads library supplies a set of low level primitives for
writing multi-threaded programs, such as mutexes and condition variables.
In fact, the first release of Boost.Threads supports only these low level
primitives. However, computer science research has shown that use of these
primitives is difficult since there&#39;s no way to mathematically prove
that a usage pattern is correct, meaning it doesn&#39;t result in race
conditions or deadlocks. There are several algebras (such as CSP, CCS and
Join calculus) that have been developed to help write provably correct
parallel processes. In order to prove the correctness these processes must
be coded using higher level abstractions. So why does Boost.Threads support
the lower level concepts?</p>
<p>The reason is simple: the higher level concepts need to be
implemented using at least some of the lower level concepts. So having
portable lower level concepts makes it easier to develop the higher
level concepts and will allow researchers to experiment with various
techniques.</p>
<p>Beyond this theoretical application of higher level concepts,
however, the fact remains that many multi-threaded programs are written
using only the lower level concepts, so they are useful in and of
themselves, even if it&#39;s hard to prove that their usage is correct.
Since many users will be familiar with these lower level concepts but
be unfamiliar with any of the higher level concepts there&#39;s also an
argument for accessibility.</p>
<h2><a name="lock_objects">Rationale for the Lock Design</a></h2>
<p>Programmers who are used to multi-threaded programming issues will
quickly note that the Boost.Thread&#39;s design for mutex lock concepts
is not <a href="definitions.html#Thread-safe">thread-safe</a> (this is
clearly documented as well). At first this may seem like a serious
design flaw. Why have a multi-threading primitive that&#39;s not
thread-safe itself?</p>
<p>A lock object is not a synchronization primitive. A lock
object&#39;s sole responsibility is to ensure that a mutex is both
locked and unlocked in a manner that won&#39;t result in the common
error of locking a mutex and then forgetting to unlock it. This means
that instances of a lock object are only going to be created, at least
in theory, within block scope and won&#39;t be shared between threads.
Only the mutex objects will be created outside of block scope and/or
shared between threads. Though it&#39;s possible to create a lock
object outside of block scope and to share it between threads to do so
would not be a typical usage. Nor are there any cases when such usage
would be required.</p>
<p>Lock objects must maintain some state information. In order to allow
a program to determine if a try_lock or timed_lock was successful the
lock object must retain state indicating the success or failure of the
call made in its constructor. If a lock object were to have such state
and remain thread-safe it would need to synchronize access to the state
information which would result in roughly doubling the time of most
operations. Worse, since checking the state can occur only by a call
after construction we&#39;d have a race condition if the lock object
were shared between threads.</p>
<p>So, to avoid the overhead of synchronizing access to the state
information and to avoid the race condition the Boost.Threads library
simply does nothing to make lock objects thread-safe. Instead, sharing
a lock object between threads results in undefined behavior. Since the
only proper usage of lock objects is within block scope this isn&#39;t
a problem, and so long as the lock object is properly used there&#39;s
no danger of any multi-threading issues.</p>
<h2><a name="thread">Rationale for Non-copyable Thread Type</a></h2>
<p>Programmers who are used to C libraries for multi-threaded
programming are likely to wonder why Boost.Threads uses a non-copyable
design for <a href="thread.html">boost::thread</a>. After all, the C
thread types are copyable, and you often have a need for copying them
within user code. However, careful comparison of C designs to C++
designs shows a flaw in this logic.</p>
<p>All C types are copyable. It is, in fact, not possible to make a
non-copyable type in C. For this reason types that represent system
resources in C are often designed to behave very similarly to a pointer
to dynamic memory. There&#39;s an API for acquiring the resource and an
API for releasing the resources. For memory we have pointers as the
type and alloc/free for the acquisition and release APIs. For files we
have FILE* as the type and fopen/fclose for the acquisition and release
APIs. You can freely copy instances of the types but must manually
manage the lifetime of the actual resource through the acquisition and
release APIs.</p>
<p>C++ designs recognize that the acquisition and release APIs are
error prone and try to eliminate possible errors by acquiring the
resource in the constructor and releasing it in the destructor. The
best example of such a design is the std::iostream set of classes which
can represent the same resource as the FILE* type in C. A file is
opened in the std::fstream&#39;s constructor and closed in its
destructor. However, if an iostream were copyable it could lead to a
file being closed twice, an obvious error, so the std::iostream types
are noncopyable by design. This is the same design used by
boost::thread, which is a simple and easy to understand design
that&#39;s consistent with other C++ standard types.</p>
<p>During the design of boost::thread it was pointed out that it would
be possible to allow it to be a copyable type if some form of
&quot;reference management&quot; were used, such as ref-counting or
ref-lists, and many argued for a boost::thread_ref design instead. The
reasoning was that copying &quot;thread&quot; objects was a typical
need in the C libraries, and so presumably would be in the C++
libraries as well. It was also thought that implementations could
provide more efficient reference management then wrappers (such as
boost::shared_ptr) around a noncopyable thread concept. Analysis of
whether or not these arguments would hold true don&#39;t appear to bear
them out. To illustrate the analysis we&#39;ll first provide
pseudo-code illustrating the six typical usage patterns of a thread
object.</p>
<h3>1. Simple creation of a thread.</h3>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Threads - Rationale</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Rationale</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#library">Rationale for the Creation of <b>Boost.Threads</b></a></dt>
<dt><a href="#primitives">Rationale for the Low Level Primitives Supported in
<b>Boost.Threads</b></a></dt>
<dt><a href="#lock_objects">Rationale for the Lock Design</a></dt>
<dt><a href="#non-copyable">Rationale for Non-copyable Thread Type</a></dt>
<dt><a href="#events">Rationale for not providing <i>Event Variables</i></a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>This page explains the rationale behind various design decisions in the <b>Boost.Threads</b>
library. Having the rationale documented here should explain how we arrived
at the current design as well as prevent future rehashing of discussions and
thought processes that have already occurred. It can also give users a lot of
insight into the design process required for this library.</p>
<h2><a name="library"></a>Rationale for the Creation of <b>Boost.Threads</b></h2>
<p>Processes often have a degree of &quot;potential parallelism&quot; and it can
often be more intuitive to design systems with this in mind. Further, these
parallel processes can result in more responsive programs. The benefits for
multi-threaded programming are quite well known to most modern programmers,
yet the C++ language doesn&#39;t directly support this concept.</p>
<p>Many platforms support multi-threaded programming despite the fact that the
language doesn&#39;t support it. They do this through external libraries, which
are, unfortunately, platform specific. POSIX has tried to address this problem
through the standardization of a &quot;pthread&quot; library. However, this
is a standard only on POSIX platforms, so its portability is limited.</p>
<p>Another problem with POSIX and other platform specific thread libraries is
that they are almost universally C based libraries. This leaves several C++
specific issues unresolved, such as what happens when an exception is thrown
in a thread. Further, there are some C++ concepts, such as destructors, that
can make usage much easier than what&#39;s available in a C library.</p>
<p>What&#39;s truly needed is C++ language support for threads. However, the C++
standards committee needs existing practice or a good proposal as a starting
point for adding this to the standard.</p>
<p>The <b>Boost.Threads</b> library was developed to provide a C++ developer with
a portable interface for writing multi-threaded programs on numerous platforms.
There&#39;s a hope that the library can be the basis for a more detailed proposal
for the C++ standards committee to consider for inclusion in the next C++ standard.</p>
<h2><a name="primitives"></a>Rationale for the Low Level Primitives Supported
in <b>Boost.Threads</b></h2>
<p>The <b>Boost.Threads</b> library supplies a set of low level primitives for
writing multi-threaded programs, such as mutexes and condition variables. In
fact, the first release of <b>Boost.Threads</b> supports only these low level
primitives. However, computer science research has shown that use of these primitives
is difficult since there&#39;s no way to mathematically prove that a usage pattern
is correct, meaning it doesn&#39;t result in race conditions or deadlocks. There
are several algebras (such as CSP, CCS and Join calculus) that have been developed
to help write provably correct parallel processes. In order to prove the correctness
these processes must be coded using higher level abstractions. So why does <b>Boost.Threads</b>
support the lower level concepts?</p>
<p>The reason is simple: the higher level concepts need to be implemented using
at least some of the lower level concepts. So having portable lower level concepts
makes it easier to develop the higher level concepts and will allow researchers
to experiment with various techniques.</p>
<p>Beyond this theoretical application of higher level concepts, however, the
fact remains that many multi-threaded programs are written using only the lower
level concepts, so they are useful in and of themselves, even if it&#39;s hard
to prove that their usage is correct. Since many users will be familiar with
these lower level concepts but be unfamiliar with any of the higher level concepts
there&#39;s also an argument for accessibility.</p>
<h2><a name="lock_objects"></a>Rationale for the Lock Design</h2>
<p>Programmers who are used to multi-threaded programming issues will quickly
note that the Boost.Thread&#39;s design for mutex lock concepts is not <a href="definitions.html#Thread-safe">thread-safe</a>
(this is clearly documented as well). At first this may seem like a serious
design flaw. Why have a multi-threading primitive that&#39;s not thread-safe
itself?</p>
<p>A lock object is not a synchronization primitive. A lock object&#39;s sole
responsibility is to ensure that a mutex is both locked and unlocked in a manner
that won&#39;t result in the common error of locking a mutex and then forgetting
to unlock it. This means that instances of a lock object are only going to be
created, at least in theory, within block scope and won&#39;t be shared between
threads. Only the mutex objects will be created outside of block scope and/or
shared between threads. Though it&#39;s possible to create a lock object outside
of block scope and to share it between threads to do so would not be a typical
usage. Nor are there any cases when such usage would be required.</p>
<p>Lock objects must maintain some state information. In order to allow a program
to determine if a try_lock or timed_lock was successful the lock object must
retain state indicating the success or failure of the call made in its constructor.
If a lock object were to have such state and remain thread-safe it would need
to synchronize access to the state information which would result in roughly
doubling the time of most operations. Worse, since checking the state can occur
only by a call after construction we&#39;d have a race condition if the lock
object were shared between threads.</p>
<p>So, to avoid the overhead of synchronizing access to the state information
and to avoid the race condition the <b>Boost.Threads</b> library simply does
nothing to make lock objects thread-safe. Instead, sharing a lock object between
threads results in undefined behavior. Since the only proper usage of lock objects
is within block scope this isn&#39;t a problem, and so long as the lock object
is properly used there&#39;s no danger of any multi-threading issues.</p>
<h2><a name="non-copyable"></a>Rationale for Non-copyable Thread Type</h2>
<p>Programmers who are used to C libraries for multi-threaded programming are
likely to wonder why <b>Boost.Threads</b> uses a non-copyable design for <a href="thread.html">boost::thread</a>.
After all, the C thread types are copyable, and you often have a need for copying
them within user code. However, careful comparison of C designs to C++ designs
shows a flaw in this logic.</p>
<p>All C types are copyable. It is, in fact, not possible to make a non-copyable
type in C. For this reason types that represent system resources in C are often
designed to behave very similarly to a pointer to dynamic memory. There&#39;s
an API for acquiring the resource and an API for releasing the resources. For
memory we have pointers as the type and alloc/free for the acquisition and release
APIs. For files we have FILE* as the type and fopen/fclose for the acquisition
and release APIs. You can freely copy instances of the types but must manually
manage the lifetime of the actual resource through the acquisition and release
APIs.</p>
<p>C++ designs recognize that the acquisition and release APIs are error prone
and try to eliminate possible errors by acquiring the resource in the constructor
and releasing it in the destructor. The best example of such a design is the
std::iostream set of classes which can represent the same resource as the FILE*
type in C. A file is opened in the std::fstream&#39;s constructor and closed
in its destructor. However, if an iostream were copyable it could lead to a
file being closed twice, an obvious error, so the std::iostream types are noncopyable
by design. This is the same design used by boost::thread, which is a simple
and easy to understand design that&#39;s consistent with other C++ standard
types.</p>
<p>During the design of boost::thread it was pointed out that it would be possible
to allow it to be a copyable type if some form of &quot;reference management&quot;
were used, such as ref-counting or ref-lists, and many argued for a boost::thread_ref
design instead. The reasoning was that copying &quot;thread&quot; objects was
a typical need in the C libraries, and so presumably would be in the C++ libraries
as well. It was also thought that implementations could provide more efficient
reference management then wrappers (such as boost::shared_ptr) around a noncopyable
thread concept. Analysis of whether or not these arguments would hold true don&#39;t
appear to bear them out. To illustrate the analysis we&#39;ll first provide
pseudo-code illustrating the six typical usage patterns of a thread object.</p>
<h3>1. Simple creation of a thread.</h3>
<pre>
void foo()
{
create_thread(&amp;bar);
}
</pre>
<h3>2. Creation of a thread that&#39;s later joined.</h3>
<h3>2. Creation of a thread that's later joined.</h3>
<pre>
void foo()
{
@@ -196,8 +157,7 @@ void foo()
join(thread);
}
</pre>
<h3>3. Simple creation of several threads in a loop.</h3>
<h3>3. Simple creation of several threads in a loop.</h3>
<pre>
void foo()
{
@@ -205,9 +165,7 @@ void foo()
create_thread(&amp;bar);
}
</pre>
<h3>4. Creation of several threads in a loop which are later
joined.</h3>
<h3>4. Creation of several threads in a loop which are later joined.</h3>
<pre>
void foo()
{
@@ -217,9 +175,7 @@ void foo()
threads[i].join();
}
</pre>
<h3>5. Creation of a thread whose ownership is passed to another
object/method.</h3>
<h3>5. Creation of a thread whose ownership is passed to another object/method.</h3>
<pre>
void foo()
{
@@ -227,9 +183,7 @@ void foo()
manager.owns(thread);
}
</pre>
<h3>6. Creation of a thread whose ownership is shared between multiple
objects.</h3>
<h3>6. Creation of a thread whose ownership is shared between multiple objects.</h3>
<pre>
void foo()
{
@@ -238,33 +192,24 @@ void foo()
manager2.add(thread);
}
</pre>
<p>Of these usage patterns there&#39;s only one that requires reference
management (number 6). Hopefully it&#39;s fairly obvious that this
usage pattern simply won&#39;t occur as often as the other usage
patterns. So there really isn&#39;t a &quot;typical need&quot; for a
thread concept, though there is some need.</p>
<p>Since the need isn&#39;t typical we must use different criteria for
deciding on either a thread_ref or thread design. Possible criteria
include ease of use and performance. So let&#39;s analyze both of these
carefully.</p>
<p>With ease of use we can look at existing experience. The standard
C++ objects that represent a system resource, such as std::iostream,
are noncopyable, so we know that C++ programmers must at least be
experienced with this design. Most C++ developers are also used to
smart pointers such as boost::shared_ptr, so we know they can at least
adapt to a thread_ref concept with little effort. So existing
experience isn&#39;t going to lead us to a choice.</p>
<p>The other thing we can look at is how difficult it is to use both
types for the six usage patterns above. If we find it overly difficult
to use a concept for any of the usage patterns there would be a good
argument for choosing the other design. So we&#39;ll code all six usage
patterns using both designs.</p>
<h3>1.</h3>
<p>Of these usage patterns there&#39;s only one that requires reference management
(number 6). Hopefully it&#39;s fairly obvious that this usage pattern simply
won&#39;t occur as often as the other usage patterns. So there really isn&#39;t
a &quot;typical need&quot; for a thread concept, though there is some need.</p>
<p>Since the need isn&#39;t typical we must use different criteria for deciding
on either a thread_ref or thread design. Possible criteria include ease of use
and performance. So let&#39;s analyze both of these carefully.</p>
<p>With ease of use we can look at existing experience. The standard C++ objects
that represent a system resource, such as std::iostream, are noncopyable, so
we know that C++ programmers must at least be experienced with this design.
Most C++ developers are also used to smart pointers such as boost::shared_ptr,
so we know they can at least adapt to a thread_ref concept with little effort.
So existing experience isn&#39;t going to lead us to a choice.</p>
<p>The other thing we can look at is how difficult it is to use both types for
the six usage patterns above. If we find it overly difficult to use a concept
for any of the usage patterns there would be a good argument for choosing the
other design. So we&#39;ll code all six usage patterns using both designs.</p>
<h3>1.</h3>
<pre>
void foo()
{
@@ -276,8 +221,7 @@ void foo()
thread_ref thrd = create_thread(&amp;bar);
}
</pre>
<h3>2.</h3>
<h3>2.</h3>
<pre>
void foo()
{
@@ -291,8 +235,7 @@ void foo()
create_thread(&amp;bar);thrd-&gt;join();
}
</pre>
<h3>3.</h3>
<h3>3.</h3>
<pre>
void foo()
{
@@ -306,8 +249,7 @@ void foo()
thread_ref thrd = create_thread(&amp;bar);
}
</pre>
<h3>4.</h3>
<h3>4.</h3>
<pre>
void foo()
{
@@ -327,8 +269,7 @@ void foo()
++i)threads[i]-&gt;join();
}
</pre>
<h3>5.</h3>
<h3>5.</h3>
<pre>
void foo()
{
@@ -342,8 +283,7 @@ void foo()
manager.owns(thrd);
}
</pre>
<h3>6.</h3>
<h3>6.</h3>
<pre>
void foo()
{
@@ -359,16 +299,14 @@ void foo()
manager2.add(thrd);
}
</pre>
<p>This shows the usage patterns being nearly identical in complexity
for both designs. The only actual added complexity occurs because of
the use of operator new in (4), (5) and (6) and the use of
std::auto_ptr and boost::shared_ptr in (4) and (6) respectively.
However, that&#39;s not really much added complexity, and C++
programmers are used to using these idioms any way. Some may dislike
the presence of operator new in user code, but this can be eliminated
by proper design of higher level concepts, such as the
boost::thread_group class that simplifies example (4) down to:</p>
<p>This shows the usage patterns being nearly identical in complexity for both
designs. The only actual added complexity occurs because of the use of operator
new in (4), (5) and (6) and the use of std::auto_ptr and boost::shared_ptr in
(4) and (6) respectively. However, that&#39;s not really much added complexity,
and C++ programmers are used to using these idioms any way. Some may dislike
the presence of operator new in user code, but this can be eliminated by proper
design of higher level concepts, such as the boost::thread_group class that
simplifies example (4) down to:</p>
<pre>
void foo()
{
@@ -378,104 +316,83 @@ void foo()
threads.join_all();
}
</pre>
<p>So ease of use is really a wash and not much help in picking a
design.</p>
<p>So what about performance? If you look at the above code examples we
can analyze the theoretical impact to performance that both designs
have. For (1) we can see that platforms that don&#39;t have a
ref-counted native thread type (POSIX, for instance) will be impacted
by a thread_ref design. Even if the native thread type is ref-counted
there may be an impact if more state information has to be maintained
for concepts foreign to the native API, such as clean up stacks for
Win32 implementations. For (2) the performance impact will be identical
to (1). The same for (3). For (4) things get a little more interesting
and we find that theoretically at least the thread_ref may perform
faster since the thread design requires dynamic memory
allocation/deallocation. However, in practice there may be dynamic
allocation for the thread_ref design as well, it will just be hidden
from the user. As long as the implementation has to do dynamic
allocations the thread_ref loses again because of the reference
management. For (5) we see the same impact as we do for (4). For (6) we
still have a possible impact to the thread design because of dynamic
allocation but thread_ref no longer suffers because of it&#39;s
reference management, and in fact, theoretically at least, the
thread_ref may do a better job of managing the references. All of this
indicates that thread wins for (1), (2) and (3), with (4) and (5) the
winner depends on the implementation and the platform but the thread
design probably has a better chance, and with (6) it will again depend
on the implementation and platform but this time we favor thread_ref
slightly. Given all of this it&#39;s a narrow margin, but the thread
design prevails.</p>
<p>Given this analysis, and the fact that noncopyable objects for
system resources are the normal designs that C++ programmers are used
to dealing with, the Boost.Threads library has gone with a noncopyable
design.</p>
<h2>Rationale for not providing <i><a name="Events">Event</a>
Variables</i></h2>
<p><i>Event variables</i> are simply far too error-prone. <a href=
"condition.html">Condition variables</a> are a much safer
alternative.</p>
<p>[Note that Graphical User Interface <i>events</i> are a different
concept, and are not what is being discussed here.]</p>
<p>Event variables were one of the first synchronization primitives.
They are still used today, for example, in the native Windows
multithreading API.</p>
<p>Yet both respected computer science researchers and experienced
multithreading practitioners believe event variables are so inherently
error-prone that they should never be used, and thus should not be part
of a multithreading library.</p>
<p>Per Brinch Hansen <a href="bibliography.html#Brinch-Hansen-73">
[Brinch Hansen 73]</a> analyzed event variables in some detail,
pointing out [emphasis his] that &quot;<i>event operations force the
programmer to be aware of the relative speeds of the sending and
receiving processes</i>&quot;. His summary:</p>
<blockquote>
<p>We must therefore conclude that event variables of the previous
type are impractical for system design. <i>The effect of an
interaction between two processes must be independent of the speed
at which it is carried out.</i></p>
</blockquote>
<p>Experienced programmers using the Windows platform today report that
event variables are a continuing source of errors, even after previous
bad experiences caused them to be very careful in their use of event
variables. Overt problems can be avoided, for example, by teaming the
event variable with a mutex, but that may just convert a <a href=
"definitions.html#Race condition">race condition</a> into another
problem, such as excessive resource use. One of the most distressing
aspects of the experience reports is the claim that many defects are
latent. That is, the programs appear to work correctly, but contain
hidden timing dependencies which will cause them to fail when
environmental factors or usage patterns change, altering relative
thread timings.</p>
<p>The decision to exclude event variables from Boost.Threads has been
surprising to some Windows programmers. They have written programs
which work using event variables, and wonder what the problem is. It
seems similar to the &quot;goto considered harmful&quot; controversy of
30 years ago. It isn&#39;t that events, like gotos, can&#39;t be made
to work, but rather that virtually all programs using alternatives will
be easier to write, debug, read, maintain, and be less likely to
contain latent defects.</p>
<p>[Rationale provided by Beman Dawes]</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->05 November, 2001<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p><i>&copy; Copyright <a href="mailto:williamkempf@hotmail.com">
William E. Kempf</a> 2001 all rights reserved.</i></p>
</body>
<p>So ease of use is really a wash and not much help in picking a design.</p>
<p>So what about performance? If you look at the above code examples we can analyze
the theoretical impact to performance that both designs have. For (1) we can
see that platforms that don&#39;t have a ref-counted native thread type (POSIX,
for instance) will be impacted by a thread_ref design. Even if the native thread
type is ref-counted there may be an impact if more state information has to
be maintained for concepts foreign to the native API, such as clean up stacks
for Win32 implementations. For (2) the performance impact will be identical
to (1). The same for (3). For (4) things get a little more interesting and we
find that theoretically at least the thread_ref may perform faster since the
thread design requires dynamic memory allocation/deallocation. However, in practice
there may be dynamic allocation for the thread_ref design as well, it will just
be hidden from the user. As long as the implementation has to do dynamic allocations
the thread_ref loses again because of the reference management. For (5) we see
the same impact as we do for (4). For (6) we still have a possible impact to
the thread design because of dynamic allocation but thread_ref no longer suffers
because of it&#39;s reference management, and in fact, theoretically at least,
the thread_ref may do a better job of managing the references. All of this indicates
that thread wins for (1), (2) and (3), with (4) and (5) the winner depends on
the implementation and the platform but the thread design probably has a better
chance, and with (6) it will again depend on the implementation and platform
but this time we favor thread_ref slightly. Given all of this it&#39;s a narrow
margin, but the thread design prevails.</p>
<p>Given this analysis, and the fact that noncopyable objects for system resources
are the normal designs that C++ programmers are used to dealing with, the <b>Boost.Threads</b>
library has gone with a noncopyable design.</p>
<h2><a name="events"></a>Rationale for not providing <i>Event Variables</i></h2>
<p><i>Event variables</i> are simply far too error-prone. <a href=
"condition.html">Condition variables</a> are a much safer alternative.</p>
<p>[Note that Graphical User Interface <i>events</i> are a different concept,
and are not what is being discussed here.]</p>
<p>Event variables were one of the first synchronization primitives. They are
still used today, for example, in the native Windows multithreading API.</p>
<p>Yet both respected computer science researchers and experienced multithreading
practitioners believe event variables are so inherently error-prone that they
should never be used, and thus should not be part of a multithreading library.</p>
<p>Per Brinch Hansen <a href="bibliography.html#Brinch-Hansen-73"> [Brinch Hansen
73]</a> analyzed event variables in some detail, pointing out [emphasis his]
that &quot;<i>event operations force the programmer to be aware of the relative
speeds of the sending and receiving processes</i>&quot;. His summary:</p>
<blockquote>
<p>We must therefore conclude that event variables of the previous type are
impractical for system design. <i>The effect of an interaction between two
processes must be independent of the speed at which it is carried out.</i></p>
</blockquote>
<p>Experienced programmers using the Windows platform today report that event
variables are a continuing source of errors, even after previous bad experiences
caused them to be very careful in their use of event variables. Overt problems
can be avoided, for example, by teaming the event variable with a mutex, but
that may just convert a <a href=
"definitions.html#Race condition">race condition</a> into another problem,
such as excessive resource use. One of the most distressing aspects of the experience
reports is the claim that many defects are latent. That is, the programs appear
to work correctly, but contain hidden timing dependencies which will cause them
to fail when environmental factors or usage patterns change, altering relative
thread timings.</p>
<p>The decision to exclude event variables from <b>Boost.Threads</b> has been
surprising to some Windows programmers. They have written programs which work
using event variables, and wonder what the problem is. It seems similar to the
&quot;goto considered harmful&quot; controversy of 30 years ago. It isn&#39;t
that events, like gotos, can&#39;t be made to work, but rather that virtually
all programs using alternatives will be easier to write, debug, read, maintain,
and be less likely to contain latent defects.</p>
<p>[Rationale provided by Beman Dawes]</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="mailto:wekempf@cox.net">William E. Kempf</a> 2001-2002.
All Rights Reserved.</i></p>
<p>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation. William E. Kempf
makes no representations about the suitability of this software for any purpose.
It is provided &quot;as is&quot; without express or implied warranty.</p>
</body>
</html>

View File

@@ -1,92 +1,94 @@
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<meta name="keywords" content=
"threads, Boost.Threads, thread library, C++">
<link rel="stylesheet" type="text/css" href="styles.css">
<title>Boost.Threads, thread</title>
</head>
<body bgcolor="#ffffff" link="#0000ff" vlink="#800080">
<table summary="header" border="0" cellpadding="7" cellspacing="0"
width="100%">
<tr>
<td valign="top" width="300">
<h3><img height="86" alt="C++ Boost" src=
"../../../c++boost.gif" width="277"></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Class thread</h2>
</td>
</tr>
</table>
<hr>
<p><a href="#Introduction">Introduction</a><br>
<a href="#Header">Header</a><br>
<a href="#Synopsis">Synopsis</a><br>
<a href="#Members">Members</a><br>
<a href="#Example">Example</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <code>thread</code> class represents threads of execution, and
provides the functionality to create and manage threads within the <b>
Boost.Threads</b> library. See <a href="definitions.html">
Definitions</a> for a precise description of &quot;thread of
execution&quot;, and for definitions of threading related terms and of
thread states such as &quot;blocked&quot;.</p>
<p>A thread of execution has an initial function. For the program&#39;s
initial thread, the initial function is <code>main()</code>. For other
threads, the initial function is <code>operator()</code> of the
function object passed to the class <code>thread</code>
constructor.</p>
<p>A thread of execution is said to be &quot;finished&quot; or
&quot;finished execution&quot; when its initial function returns or is
terminated. This includes completion of all thread cleanup handlers,
and completion of the normal C++ function return behaviors, such as
destruction of automatic storage (stack) objects and releasing any
associated implementation resources.</p>
<p>A thread object has an associated state which is either
&quot;joinable&quot; or &quot;non-joinable&quot;.</p>
<p>Except as described below, the policy used by an implementation of
<b>Boost.Threads</b> to schedule transitions between thread states is
unspecified.</p>
<p><b>Note:</b> Just as the lifetime of a file may be different from
the lifetime of an iostream object which represents the file, the
lifetime of a thread of execution may be different from the <code>
thread</code> object which represents the thread of execution. In
particular, after a call to <code>join()</code>, the thread of
execution will no longer exist even though the <code>thread</code>
object continues to exist until the end of its normal lifetime. The
converse is also possible; if a <code>thread</code> object is destroyed
without <code>join()</code> having first been called, the thread of
execution continues until its initial function completes.</p>
<h2><a name="Header">Header</a></h2>
<pre>
#include <a href=
"../../../boost/thread/thread.hpp">&lt;boost/thread/thread.hpp&gt;</a>
</pre>
<h2><a name="Synopsis">Synopsis</a></h2>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Threads - &lt;boost/thread.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Header &lt;boost/thread.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dl class="page-index">
<dt><a href="#class-thread">Class <code>thread</code></a></dt>
<dl class="page-index">
<dt><a href="#class-thread-synopsis">Class <code>thread</code> synopsis</a></dt>
<dt><a href="#class-thread-ctors">Class <code>thread</code> constructors
and destructor</a></dt>
<dt><a href="#class-thread-comparisons">Class <code>thread</code>
comparison functions</a></dt>
<dt><a href="#class-thread-modifiers">Class <code>thread</code> modifier
functions</a></dt>
<dt><a href="#class-thread-statics">Class <code>thread</code> static
functions</a></dt>
</dl>
<dt><a href="#class-thread_group">Class <code>thread_group</code></a></dt>
<dl class="page-index">
<dt><a href="#class-thread_group-synopsis">Class <code>thread_group</code> synopsis</a></dt>
<dt><a href="#class-thread_group-ctors">Class <code>thread_group</code> constructors
and destructor</a></dt>
<dt><a href="#class-thread_group-modifiers">Class <code>thread_group</code> modifier
functions</a></dt>
</dl>
</dl>
<dt><a href="#examples">Example(s)</a></dt>
<dl class="page-index">
<dt><a href="#example-thread">Simple usage of <code>boost::thread</code></a></dt>
<dt><a href="#example-thread_group">Simple usage of <code>boost::thread_group</code></a></dt>
</dl>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>The <code>boost/thread.hpp</code> header contains classes used to create and manage threads.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class-thread"></a>Class <code>thread</code></h3>
<p>The <code>thread</code> class represents threads of execution, and provides
the functionality to create and manage threads within the <b> Boost.Threads</b>
library. See <a href="definitions.html"> Definitions</a> for a precise description
of &quot;thread of execution&quot;, and for definitions of threading related
terms and of thread states such as &quot;blocked&quot;.</p>
<p>A thread of execution has an initial function. For the program&#39;s initial
thread, the initial function is <code>main()</code>. For other threads, the
initial function is <code>operator()</code> of the function object passed to
the class <code>thread</code> constructor.</p>
<p>A thread of execution is said to be &quot;finished&quot; or &quot;finished
execution&quot; when its initial function returns or is terminated. This includes
completion of all thread cleanup handlers, and completion of the normal C++
function return behaviors, such as destruction of automatic storage (stack)
objects and releasing any associated implementation resources.</p>
<p>A thread object has an associated state which is either &quot;joinable&quot;
or &quot;non-joinable&quot;.</p>
<p>Except as described below, the policy used by an implementation of <b>Boost.Threads</b>
to schedule transitions between thread states is unspecified.</p>
<p><b>Note:</b> Just as the lifetime of a file may be different from the lifetime
of an iostream object which represents the file, the lifetime of a thread of
execution may be different from the <code> thread</code> object which represents
the thread of execution. In particular, after a call to <code>join()</code>,
the thread of execution will no longer exist even though the <code>thread</code>
object continues to exist until the end of its normal lifetime. The converse
is also possible; if a <code>thread</code> object is destroyed without <code>join()</code>
having first been called, the thread of execution continues until its initial
function completes.</p>
<h4><a name="class-thread-synopsis"></a>Class <code>thread</code> synopsis</h4>
<pre>
namespace boost {
class thread : <a href=
"../../utility/utility.htm#noncopyable">boost::noncopyable</a> // Exposition only.
"../../utility/utility.htm#Class noncopyable">boost::noncopyable</a> // Exposition only.
// Class thread meets the <a href=
"overview.html#NonCopyable">NonCopyable</a> requirement.
"overview.html#non-copyable">NonCopyable</a> requirement.
{
public:
thread();
@@ -101,119 +103,192 @@ public:
static void sleep(const xtime&amp; xt);
static void yield();
};
} // namespace boost
</pre>
<h2><a name="Members">Members</a></h2>
<hr>
<h3>Constructors</h3>
<h4><a name="class-thread-ctors"></a>Class <code>thread</code> constructors and destructor</h4>
<pre>
thread();
thread();
</pre>
<p><b>Effects:</b> Constructs a <code>thread</code> object representing
the current thread of execution.</p>
<p><b>Postcondition:</b> <code>*this</code> is non-joinable.</p>
<p><b>Danger:</b> <code>*this</code> is valid only within the current
thread.</p>
<dl class="function-semantics">
<dt><b>Effects:</b> Constructs a <code>thread</code> object representing
the current thread of execution.</dt>
<dt><b>Postconditions:</b> <code>*this</code> is non-joinable.</dt>
<dt><b>Danger:</b> <code>*this</code> is valid only within the current
thread.</dt>
</dl>
<pre>
thread(const <a href=
"../../function/index.html">boost::function0</a>&lt;void&gt;&amp; threadfunc);
thread(const <a href="../../function/index.html">boost::function0</a>&lt;void&gt;&amp; threadfunc);
</pre>
<p><b>Effects:</b> Starts a new thread of execution and constructs a
<dl class="function-semantics">
<dt><b>Effects:</b> Starts a new thread of execution and constructs a
<code>thread</code> object representing it. Copies <code>
threadfunc</code> (which in turn copies the function object wrapped by
<code>threadfunc</code>) to an internal location which persists for the
lifetime of the new thread of execution. Calls <code>operator()</code>
on the copy of the <code>threadfunc</code> function object in the new
thread of execution.</p>
<p><b>Postcondition:</b> <code>*this</code> is joinable.</p>
<p><b>Throws:</b> <code>boost::thread_resource_error</code> if a new
thread of execution cannot be started.</p>
<hr>
<h3>Destructor</h3>
thread of execution.</dt>
<dt><b>Postconditions:</b> <code>*this</code> is joinable.</dt>
<dt><b>Throws:</b> <code>boost::thread_resource_error</code> if a new
thread of execution cannot be started.</dt>
</dl>
<pre>
~thread();
~thread();
</pre>
<p><b>Effects:</b> Destroys <code>*this</code>. The actual thread of
<dl class="function-semantics">
<dt><b>Effects:</b> Destroys <code>*this</code>. The actual thread of
execution may continue to execute after the <code>thread</code> object
has been destroyed.</p>
<p><b>Notes:</b> If <code>*this</code> is joinable the actual thread of
has been destroyed.</dt>
<dt><b>Note:</b> If <code>*this</code> is joinable the actual thread of
execution becomes &quot;detached&quot;. Any resources used by the
thread will be reclaimed when the thread of execution completes. To
ensure such a thread of execution runs to completion before the <code>
thread</code> object is destroyed, call <code>join()</code>.</p>
<hr>
<h3>Comparison Operators</h3>
thread</code> object is destroyed, call <code>join()</code>.</dt>
</dl>
<h4><a name="class-thread-comparisons"></a>Class <code>thread</code> comparison functions</h4>
<pre>
bool operator==(const thread&amp; rhs);
bool operator==(const thread&amp; rhs) const;
</pre>
<p><b>Requires:</b> The thread is non-terminated or <code>*this</code>
is joinable.</p>
<p><b>Returns:</b> <code>true</code> if <code>*this</code> and <code>
rhs</code> represent the same thread of execution.</p>
<dl class="function-semantics">
<dt><b>Requires:</b> The thread is non-terminated or <code>*this</code>
is joinable.</dt>
<dt><b>Returns:</b> <code>true</code> if <code>*this</code> and <code>
rhs</code> represent the same thread of execution.</dt>
</dl>
<pre>
bool operator!=(const thread&amp; rhs);
bool operator!=(const thread&amp; rhs) const;
</pre>
<p><b>Returns:</b> <code>!(*this==rhs)</code>.</p>
<hr>
<h3>join</h3>
<dl class="function-semantics">
<dt><b>Requires:</b> The thread is non-terminated or <code>*this</code>
is joinable.</dt>
<dt><b>Returns:</b> <code>!(*this==rhs)</code>.</dt>
</dl>
<h4><a name="class-thread-modifiers"></a>Class <code>thread</code> modifier functions</h4>
<pre>
void join();
void join();
</pre>
<p><b>Requires:</b> <code>*this</code> is joinable.</p>
<p><b>Effects:</b> The current thread of execution blocks until the
<dl class="function-semantics">
<dt><b>Requires:</b> <code>*this</code> is joinable.</dt>
<dt><b>Effects:</b> The current thread of execution blocks until the
initial function of the thread of execution represented by <code>
*this</code> finishes and all resources are reclaimed.</p>
<p><b>Postcondition:</b> <code>*this</code> is non-joinable.</p>
<p><b>Note:</b> If <code>*this == thread()</code> the result is
*this</code> finishes and all resources are reclaimed.</dt>
<dt><b>Postconditions:</b> <code>*this</code> is non-joinable.</dt>
<dt><b>Notes:</b> If <code>*this == thread()</code> the result is
implementation defined. If the implementation doesn&#39;t detect this
the result will be <a href="definitions.html#Deadlock">
deadlock</a>.</p>
<hr>
<h3>sleep</h3>
deadlock</a>.</dt>
</dl>
<h4><a name="class-thread-statics"></a>Class <code>thread</code> static functions</h4>
<pre>
static void sleep(const <a href="xtime.html">xtime</a>&amp; xt);
static void sleep(const <a href="xtime.html">xtime</a>&amp; xt);
</pre>
<p><b>Effects:</b> The current thread of execution blocks until <code>
xt</code> is reached.</p>
<hr>
<h3>yield</h3>
<dl class="function-semantics">
<dt><b>Effects:</b> The current thread of execution blocks until <code>
xt</code> is reached.</dt>
</dl>
<pre>
static void yield();
static void yield();
</pre>
<p><b>Effects:</b> The current thread of execution is placed in the
&quot;ready&quot; state.</p>
<p><b>Notes:</b> Allow the current thread to give up the rest of its
<dl class="function-semantics">
<dt><b>Effects:</b> The current thread of execution is placed in the
&quot;ready&quot; state.</dt>
<dt><b>Notes:</b> Allow the current thread to give up the rest of its
time slice (or other scheduling quota) to another thread. Particularly
useful in non-preemptive implementations.</p>
<hr>
useful in non-preemptive implementations.</dt>
</dl>
<h3><a name="class-thread_group"></a>Class <code>thread_group</code></h3>
<p>The <tt>thread_group</tt> class provides a container for easy
grouping of threads to simplify several common thread creation and
management idioms.</p>
<h2><a name="Example">Example Usage</a></h2>
<p>All <tt>thread_group</tt> member functions are <a href=
"definitions.html#thread-safe">thread-safe</a>, except destruction.</p>
<h4><a name="class-thread_group-synopsis"></a>Class <code>thread_group</code> synopsis</h4>
<pre>
namespace boost {
class thread_group : <a href=
"../../utility/utility.htm#Class noncopyable">boost::noncopyable</a>
{
public:
thread_group();
~thread_group();
thread* create_thread(const boost::function0&lt;void&gt;&amp; threadfunc);
void add_thread(thread* thrd);
void remove_thread(thread* thrd);
void join_all();
};
} // namespace boost
</pre>
<h4><a name="class-thread_group-ctors"></a>Class <code>thread_group</code> constructors and destructor</h4>
<pre>
thread_group();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Constructs an empty <code>thread_group</code>
container.</dt>
</dl>
<pre>
~thread_group();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Destroys each contained thread object. Destroys
<code>*this</code>.</dt>
<dt><b>Notes:</b> Behavior is undefined if another thread references
*this during the execution of the destructor.</dt>
</dl>
<h4><a name="class-thread_group-modifiers"></a>Class <code>thread_group</code> modifier functions</h4>
<pre>
thread* create_thread(const boost::function0&lt;void&gt;&amp; threadfunc);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Creates a new <tt>thread</tt> object that executes
<tt>threadfunc</tt> and adds it to the <tt>thread_group</tt> container
object&#39;s list of managed <tt>thread</tt> objects.</dt>
<dt><b>Returns:</b> Pointer to the newly created thread.</dt>
</dl>
<pre>
void add_thread(thread* thrd);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Adds <tt>thrd</tt> to the <tt>thread_group</tt>
object&#39;s list of managed <tt>thread</tt> objects. The <tt>thrd</tt>
object must have been allocated via operator new and will be deleted
when the group is destroyed.</dt>
</dl>
<pre>
void remove_thread(thread* thrd);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Removes <code>*this</code>&#39;s list of managed
<tt>thread</tt> objects.</dt>
<dt><b>Throws:</b> ? if <tt>thrd</tt> is not it <code>*this</code>&#39;s
list of managed <tt>thread</tt> objects.</dt>
</dl>
<pre>
void join_all();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Calls <code>join()</code> on each of the managed
<tt>thread</tt> objects.</dt>
</dl>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="function-spec"></a>{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}</dt>
<dt><b>Effects:</b> {{text}}</dt>
<dt><b>Postconditions:</b> {{text}}</dt>
<dt><b>Returns:</b> {{text}}</dt>
<dt><b>Throws:</b> {{text}}</dt>
<dt><b>Complexity:</b> {{text}}</dt>
<dt><b>Rationale:</b> {{text}}</dt>
</dl>
<h2><a name="objects"></a>Objects</h2>
<p><a name="object-spec"></a>{{Object specifications}}</p>
<h2><a name="examples"></a>Example(s)</h2>
<h3><a name="example-thread"></a>Simple usage of <code>boost::thread</code></h3>
<pre>
#include &lt;boost/thread/thread.hpp&gt;
#include &lt;iostream&gt;
@@ -250,13 +325,48 @@ int main(int argc, char* argv[])
setting alarm for 5 seconds...
alarm sounded...
</pre>
<hr>
<h3><a name="example-thread_group"></a>Simple usage of <code>boost::thread_group</code></h3>
<pre>
#include &lt;boost/thread/thread.hpp&gt;
#include &lt;iostream&gt;
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->05 November, 2001<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
int count = 0;
boost::mutex mutex;
<p><i>&copy; Copyright <a href="mailto:williamkempf@hotmail.com">
William E. Kempf</a> 2001 all rights reserved.</i></p>
</body>
void increment_count()
{
boost::mutex::lock lock(mutex);
std::cout &lt;&lt; &quot;count = &quot; &lt;&lt; ++count &lt;&lt; std::endl;
}
int main(int argc, char* argv[])
{
boost::thread_group threads;
for (int i = 0; i &lt; 10; ++i)
threads.create_thread(&amp;increment_count);
threads.join_all();
}
</pre>
<p>The output is:</p>
<pre>
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="mailto:{{address}}">{{author}}</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

2
example/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
bin
*.pdb

View File

@@ -9,58 +9,60 @@
# 1. monitor, an example program.
# 2. starvephil, an example program.
# 3. tennis, an example program.
# Additional configuration variables used:
# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
# library should be used instead of "native" threads. This feature is
# mostly used for testing and it's generally recommended you use the
# native threading libraries instead. PTW32 should be set to be a list
# of two strings, the first specifying the installation path of the
# pthreads-win32 library and the second specifying which library
# variant to link against (see the pthreads-win32 documentation).
# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
# declare the location of this subproject relative to the root
# Declare the location of this subproject relative to the root.
subproject libs/thread/example ;
# Do some OS-specific setup
if $(NT)
{
BOOST_THREADMON_LIB = <lib>../build/libboost_threadmon ;
}
else
{
BOOST_THREADMON_LIB = ;
}
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
SEARCH on <module@>threads.jam = $(BOOST_ROOT)/libs/thread/build ;
include <module@>threads.jam ;
#######################
# Declare the Boost.Threads example program monitor.
#
# Declare the Boost.Threads monitor example program.
#
exe monitor : monitor/monitor.cpp
<lib>../build/libboost_thread
$(BOOST_THREADMON_LIB)
# requirements
exe monitor
: monitor/monitor.cpp
<lib>../build/boost_thread
$(threadmon)
: <include>$(BOOST_ROOT)
<threading>multi
: debug release ;
$(pthreads-win32)
<threading>multi
: debug release <runtime-link>static/dynamic
;
#######################
# Declare the Boost.Threads example program starvephil.
#
# Declare the Boost.Threads starvephil example program.
#
exe starvephil : starvephil/starvephil.cpp
<lib>../build/libboost_thread
$(BOOST_THREADMON_LIB)
# requirements
exe starvephil
: starvephil/starvephil.cpp
<lib>../build/boost_thread
$(threadmon)
: <include>$(BOOST_ROOT)
<threading>multi
: debug release ;
$(pthreads-win32)
<threading>multi
: debug release <runtime-link>static/dynamic
;
#######################
# Declare the Boost.Threads example program tennis.
#
# Declare the Boost.Threads tennis example program.
#
exe tennis : tennis/tennis.cpp
<lib>../build/libboost_thread
$(BOOST_THREADMON_LIB)
# requirements
exe tennis
: tennis/tennis.cpp
<lib>../build/boost_thread
$(threadmon)
: <include>$(BOOST_ROOT)
<threading>multi
: debug release ;
$(pthreads-win32)
<threading>multi
: debug release <runtime-link>static/dynamic
;

View File

@@ -92,7 +92,7 @@ private:
#endif
typedef typename detail::thread::lock_ops<M> lock_ops;
lock_ops::lock_state state;
typename lock_ops::lock_state state;
lock_ops::unlock(mutex, state);
#if defined(BOOST_HAS_PTHREADS)
@@ -112,7 +112,7 @@ private:
#endif
typedef typename detail::thread::lock_ops<M> lock_ops;
lock_ops::lock_state state;
typename lock_ops::lock_state state;
lock_ops::unlock(mutex, state);
bool ret = false;

View File

@@ -56,6 +56,8 @@ static void do_once()
once_callback* cb = reinterpret_cast<once_callback*>(pthread_getspecific(key));
(**cb)();
}
}
#elif defined(BOOST_HAS_MPTASKS)
void *remote_call_proxy(void *pData)
{

2
test/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
bin
*.pdb

View File

@@ -3,48 +3,38 @@
# in all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
#
# Boost.Threads build and test Jamfile
# Boost.Threads test Jamfile
#
# Declares the following targets:
# 1. test_thread, a unit test executable.
#
# Invoke with:
# Jam [-sPTW32=lib]
# Where: lib == name of pthreads-win32 link library
# Note: Not currently working completely
# Additional configuration variables used:
# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
# library should be used instead of "native" threads. This feature is
# mostly used for testing and it's generally recommended you use the
# native threading libraries instead. PTW32 should be set to be a list
# of two strings, the first specifying the installation path of the
# pthreads-win32 library and the second specifying which library
# variant to link against (see the pthreads-win32 documentation).
# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
# declare the location of this subproject relative to the root
# Declare the location of this subproject relative to the root.
subproject libs/thread/test ;
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
SEARCH on <module@>threads.jam = $(BOOST_ROOT)/libs/thread/build ;
include <module@>threads.jam ;
#######################
# Declare the Boost.Threads unit test program test_thread.
#
# Declare the Boost.Threads unit test program.
#
# Do some OS-specific setup
if $(NT)
{
if $(PTW32)
{
PTW32_REQUIREMENTS = <define>BOOST_HAS_PTHREADS <define>PtW32NoCatchWarn ;
BOOST_THREADMON_LIB = ;
}
else
{
BOOST_THREADMON_LIB = <lib>../build/libboost_threadmon ;
}
}
else
{
BOOST_THREADMON_LIB = ;
}
unit-test test_thread : test_thread.cpp
<lib>../build/libboost_thread
$(BOOST_THREADMON_LIB)
# requirements
unit-test test_thread
: test_thread.cpp
<lib>../build/boost_thread
$(threadmon)
: <include>$(BOOST_ROOT)
$(PTW32_REQUIREMENTS)
<threading>multi
: debug release ;
$(pthreads-win32)
<threading>multi
: debug release <runtime-link>static/dynamic
;