mirror of
https://github.com/boostorg/thread.git
synced 2026-02-08 11:12:23 +00:00
Compare commits
17 Commits
boost-1.27
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8bd5fe1d8 | ||
|
|
2775a2a945 | ||
|
|
c43c1febba | ||
|
|
ceb6471d57 | ||
|
|
b99cc044f3 | ||
|
|
d91429dcec | ||
|
|
b1d1f7d8f1 | ||
|
|
86b608cf41 | ||
|
|
f263f75751 | ||
|
|
24bec05b86 | ||
|
|
ce1a5e9359 | ||
|
|
311525bc06 | ||
|
|
ecdfd96529 | ||
|
|
5aab32bc1a | ||
|
|
e152a1c6f2 | ||
|
|
e84fde78ec | ||
|
|
6ec4652bcf |
2
build/.cvsignore
Normal file
2
build/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
bin*
|
||||
*.pdb
|
||||
@@ -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
23
build/threads.jam
Normal 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 ;
|
||||
}
|
||||
}
|
||||
@@ -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"><boost/config.hpp></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'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>© 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
94
doc/configuration.html
Normal 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"><boost/config.hpp></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'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>© 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 "as is" without express or implied warranty.</p>
|
||||
</body>
|
||||
</html>
|
||||
291
doc/index.html
291
doc/index.html
@@ -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>© <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
|
||||
"as is" 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"><boost/condition.hpp></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"><boost/mutex.hpp></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"><boost/recursive_mutex.hpp></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"><boost/tss.hpp></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"><boost/thread.hpp></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"><boost/xtime.hpp></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>© 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 "as is" without express or implied warranty.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -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's world, it'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++'s
|
||||
strengths, or to address C++'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'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 "native" 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 "state of the art" and the
|
||||
only concepts available to programmers. Recently there has been a lot
|
||||
of research in other concepts, such as in "Communicating
|
||||
Sequential Processes." <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's a big
|
||||
problem faced by developers wishing to supply such high quality
|
||||
libraries, namely thread-safety. The C++ standard doesn't address
|
||||
threads at all, but real world programs often make use of native
|
||||
threading support. A portable library that doesn'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'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 "core" 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>© 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's
|
||||
world, it'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++'s strengths, or to address C++'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'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 "native" 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 "state of the art"
|
||||
and the only concepts available to programmers. Recently there has been a lot
|
||||
of research in other concepts, such as in "Communicating Sequential Processes."
|
||||
<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's a big problem faced by developers
|
||||
wishing to supply such high quality libraries, namely thread-safety. The C++
|
||||
standard doesn't address threads at all, but real world programs often make
|
||||
use of native threading support. A portable library that doesn'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'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 "core" 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>© 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 "as is" without express or implied warranty.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -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 < num_threads; ++i)
|
||||
thrds.create_thread(&change_count, 0);
|
||||
thrds.create_thread(&change_count);
|
||||
|
||||
thrds.join_all();
|
||||
|
||||
|
||||
@@ -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 "deadly embrace")</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'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'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 "deadly
|
||||
embrace")</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'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'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>© 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>© 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 "as is" without express or implied warranty.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -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 "potential parallelism"
|
||||
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't
|
||||
directly support this concept.</p>
|
||||
|
||||
<p>Many platforms support multi-threaded programming despite the fact
|
||||
that the language doesn'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
|
||||
"pthread" 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's available in a C library.</p>
|
||||
|
||||
<p>What'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'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's no way to mathematically prove
|
||||
that a usage pattern is correct, meaning it doesn'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'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'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'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's not
|
||||
thread-safe itself?</p>
|
||||
|
||||
<p>A lock object is not a synchronization primitive. A lock
|
||||
object's sole responsibility is to ensure that a mutex is both
|
||||
locked and unlocked in a manner that won'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't be shared between threads.
|
||||
Only the mutex objects will be created outside of block scope and/or
|
||||
shared between threads. Though it'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'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't
|
||||
a problem, and so long as the lock object is properly used there'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'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'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'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
|
||||
"reference management" were used, such as ref-counting or
|
||||
ref-lists, and many argued for a boost::thread_ref design instead. The
|
||||
reasoning was that copying "thread" 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't appear to bear
|
||||
them out. To illustrate the analysis we'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 "potential parallelism" 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't directly support this concept.</p>
|
||||
<p>Many platforms support multi-threaded programming despite the fact that the
|
||||
language doesn'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 "pthread" 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's available in a C library.</p>
|
||||
<p>What'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'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's no way to mathematically prove that a usage pattern
|
||||
is correct, meaning it doesn'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'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'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'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's not thread-safe
|
||||
itself?</p>
|
||||
<p>A lock object is not a synchronization primitive. A lock object's sole
|
||||
responsibility is to ensure that a mutex is both locked and unlocked in a manner
|
||||
that won'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't be shared between
|
||||
threads. Only the mutex objects will be created outside of block scope and/or
|
||||
shared between threads. Though it'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'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't a problem, and so long as the lock object
|
||||
is properly used there'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'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'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'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 "reference management"
|
||||
were used, such as ref-counting or ref-lists, and many argued for a boost::thread_ref
|
||||
design instead. The reasoning was that copying "thread" 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't
|
||||
appear to bear them out. To illustrate the analysis we'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(&bar);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>2. Creation of a thread that'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(&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's only one that requires reference
|
||||
management (number 6). Hopefully it's fairly obvious that this
|
||||
usage pattern simply won't occur as often as the other usage
|
||||
patterns. So there really isn't a "typical need" for a
|
||||
thread concept, though there is some need.</p>
|
||||
|
||||
<p>Since the need isn'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'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'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'll code all six usage
|
||||
patterns using both designs.</p>
|
||||
|
||||
<h3>1.</h3>
|
||||
<p>Of these usage patterns there's only one that requires reference management
|
||||
(number 6). Hopefully it's fairly obvious that this usage pattern simply
|
||||
won't occur as often as the other usage patterns. So there really isn't
|
||||
a "typical need" for a thread concept, though there is some need.</p>
|
||||
<p>Since the need isn'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'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'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'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(&bar);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>2.</h3>
|
||||
<h3>2.</h3>
|
||||
<pre>
|
||||
void foo()
|
||||
{
|
||||
@@ -291,8 +235,7 @@ void foo()
|
||||
create_thread(&bar);thrd->join();
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>3.</h3>
|
||||
<h3>3.</h3>
|
||||
<pre>
|
||||
void foo()
|
||||
{
|
||||
@@ -306,8 +249,7 @@ void foo()
|
||||
thread_ref thrd = create_thread(&bar);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>4.</h3>
|
||||
<h3>4.</h3>
|
||||
<pre>
|
||||
void foo()
|
||||
{
|
||||
@@ -327,8 +269,7 @@ void foo()
|
||||
++i)threads[i]->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'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'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'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'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'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 "<i>event operations force the
|
||||
programmer to be aware of the relative speeds of the sending and
|
||||
receiving processes</i>". 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 "goto considered harmful" controversy of
|
||||
30 years ago. It isn't that events, like gotos, can'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>© 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'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'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'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 "<i>event operations force the programmer to be aware of the relative
|
||||
speeds of the sending and receiving processes</i>". 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
|
||||
"goto considered harmful" controversy of 30 years ago. It isn't
|
||||
that events, like gotos, can'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>© 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 "as is" without express or implied warranty.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
454
doc/thread.html
454
doc/thread.html
@@ -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 "thread of
|
||||
execution", and for definitions of threading related terms and of
|
||||
thread states such as "blocked".</p>
|
||||
|
||||
<p>A thread of execution has an initial function. For the program'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 "finished" or
|
||||
"finished execution" 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
|
||||
"joinable" or "non-joinable".</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"><boost/thread/thread.hpp></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 - <boost/thread.hpp></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 <boost/thread.hpp></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 "thread of execution", and for definitions of threading related
|
||||
terms and of thread states such as "blocked".</p>
|
||||
<p>A thread of execution has an initial function. For the program'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 "finished" or "finished
|
||||
execution" 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 "joinable"
|
||||
or "non-joinable".</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& 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><void>& threadfunc);
|
||||
thread(const <a href="../../function/index.html">boost::function0</a><void>& 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 "detached". 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& rhs);
|
||||
bool operator==(const thread& 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& rhs);
|
||||
bool operator!=(const thread& 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'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>& xt);
|
||||
static void sleep(const <a href="xtime.html">xtime</a>& 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
|
||||
"ready" 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
|
||||
"ready" 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<void>& 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<void>& 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'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'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>'s list of managed
|
||||
<tt>thread</tt> objects.</dt>
|
||||
<dt><b>Throws:</b> ? if <tt>thrd</tt> is not it <code>*this</code>'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 <boost/thread/thread.hpp>
|
||||
#include <iostream>
|
||||
@@ -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 <boost/thread/thread.hpp>
|
||||
#include <iostream>
|
||||
|
||||
<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>© 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 << "count = " << ++count << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
boost::thread_group threads;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
threads.create_thread(&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>© Copyright <a href="mailto:{{address}}">{{author}}</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
2
example/.cvsignore
Normal file
2
example/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
bin
|
||||
*.pdb
|
||||
@@ -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
|
||||
;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
2
test/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
bin
|
||||
*.pdb
|
||||
62
test/Jamfile
62
test/Jamfile
@@ -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
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user