...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The boost::thread
class is responsible for launching and managing threads. Each boost::thread
object represents a single thread of execution, or Not-a-Thread,
and at most one boost::thread
object represents a given thread of execution: objects of type boost::thread
are not copyable.
Objects of type boost::thread
are movable, however, so they can be stored in move-aware containers, and returned
from functions. This allows the details of thread creation to be wrapped in
a function.
boost::thread make_thread(); void f() { boost::thread some_thread=make_thread(); some_thread.join(); }
[Note: On compilers that support rvalue references, boost::thread
provides a proper move constructor and move-assignment operator, and therefore
meets the C++0x MoveConstructible and MoveAssignable
concepts. With such compilers, boost::thread
can therefore be used with containers that support those concepts.
For other compilers, move support is provided with a move emulation layer, so containers must explicitly detect that move emulation layer. See <boost/thread/detail/move.hpp> for details.]
A new thread is launched by passing an object of a callable type that can be
invoked with no parameters to the constructor. The object is then copied into
internal storage, and invoked on the newly-created thread of execution. If
the object must not (or cannot) be copied, then boost::ref
can
be used to pass in a reference to the function object. In this case, the user
of Boost.Thread must ensure that the referred-to
object outlives the newly-created thread of execution.
struct callable { void operator()(); }; boost::thread copies_are_safe() { callable x; return boost::thread(x); } // x is destroyed, but the newly-created thread has a copy, so this is OK boost::thread oops() { callable x; return boost::thread(boost::ref(x)); } // x is destroyed, but the newly-created thread still has a reference // this leads to undefined behaviour
If you wish to construct an instance of boost::thread
with a function or callable object that requires arguments to be supplied,
this can be done by passing additional arguments to the boost::thread
constructor:
void find_the_question(int the_answer); boost::thread deep_thought_2(find_the_question,42);
The arguments are copied into the internal thread structure:
if a reference is required, use boost::ref
, just
as for references to callable functions.
There is an unspecified limit on the number of additional arguments that can be passed.
If the function or callable object passed to the boost::thread
constructor propagates an exception when invoked that is not of type boost::thread_interrupted
,
std::terminate()
is called.
When the boost::thread
object that represents a thread of execution is destroyed the thread becomes
detached. Once a thread is detached, it will continue
executing until the invocation of the function or callable object supplied
on construction has completed, or the program is terminated. A thread can also
be detached by explicitly invoking the detach()
member function on the boost::thread
object. In this case, the boost::thread
object ceases to represent the now-detached thread, and instead represents
Not-a-Thread.
In order to wait for a thread of execution to finish, the join()
or timed_join()
member functions of the boost::thread
object must be used. join()
will block the calling thread until the thread represented by the boost::thread
object has completed. If the thread of execution represented by the boost::thread
object has already completed, or the boost::thread
object represents Not-a-Thread, then join()
returns immediately. timed_join()
is similar, except that a call to timed_join()
will also return if the thread being waited for does not complete when the
specified time has elapsed.
A running thread can be interrupted by invoking the interrupt()
member function of the corresponding
boost::thread
object. When the interrupted thread next executes one of the specified interruption points
(or if it is currently blocked whilst executing one) with
interruption enabled, then a boost::thread_interrupted
exception will be thrown in the interrupted thread. If not caught, this will
cause the execution of the interrupted thread to terminate. As with any other
exception, the stack will be unwound, and destructors for objects of automatic
storage duration will be executed.
If a thread wishes to avoid being interrupted, it can create an instance of
boost::this_thread::disable_interruption
.
Objects of this class disable interruption for the thread that created them
on construction, and restore the interruption state to whatever it was before
on destruction:
void f() { // interruption enabled here { boost::this_thread::disable_interruption di; // interruption disabled { boost::this_thread::disable_interruption di2; // interruption still disabled } // di2 destroyed, interruption state restored // interruption still disabled } // di destroyed, interruption state restored // interruption now enabled }
The effects of an instance of boost::this_thread::disable_interruption
can be temporarily reversed by constructing an instance of boost::this_thread::restore_interruption
,
passing in the boost::this_thread::disable_interruption
object in question. This will restore the interruption state to what it was
when the boost::this_thread::disable_interruption
object was constructed, and then disable interruption again when the boost::this_thread::restore_interruption
object is destroyed.
void g() { // interruption enabled here { boost::this_thread::disable_interruption di; // interruption disabled { boost::this_thread::restore_interruption ri(di); // interruption now enabled } // ri destroyed, interruption disable again } // di destroyed, interruption state restored // interruption now enabled }
At any point, the interruption state for the current thread can be queried
by calling boost::this_thread::interruption_enabled()
.
The following functions are interruption points, which
will throw boost::thread_interrupted
if interruption is enabled
for the current thread, and interruption is requested for the current thread:
Objects of class boost::thread::id
can be used to identify threads. Each running thread of execution has a unique
ID obtainable from the corresponding boost::thread
by calling the get_id()
member function, or by calling boost::this_thread::get_id()
from within the thread. Objects of class
boost::thread::id
can be copied, and used as keys in associative containers: the full range of
comparison operators is provided. Thread IDs can also be written to an output
stream using the stream insertion operator, though the output format is unspecified.
Each instance of boost::thread::id
either refers to some thread, or Not-a-Thread. Instances
that refer to Not-a-Thread compare equal to each other,
but not equal to any instances that refer to an actual thread of execution.
The comparison operators on boost::thread::id
yield a total order for every non-equal thread ID.
joinable()
join()
timed_join()
detach()
get_id()
interrupt()
hardware_concurrency()
native_handle()
operator==
operator!=
sleep()
yield()
swap()
swap()
boost::thread::id
#include <boost/thread/thread.hpp> class thread { public: thread(); ~thread(); template <class F> explicit thread(F f); template <class F,class A1,class A2,...> thread(F f,A1 a1,A2 a2,...); template <class F> thread(detail::thread_move_t<F> f); // move support thread(detail::thread_move_t<thread> x); thread& operator=(detail::thread_move_t<thread> x); operator detail::thread_move_t<thread>(); detail::thread_move_t<thread> move(); void swap(thread& x); class id; id get_id() const; bool joinable() const; void join(); bool timed_join(const system_time& wait_until); template<typename TimeDuration> bool timed_join(TimeDuration const& rel_time); void detach(); static unsigned hardware_concurrency(); typedef platform-specific-type native_handle_type; native_handle_type native_handle(); void interrupt(); bool interruption_requested() const; // backwards compatibility bool operator==(const thread& other) const; bool operator!=(const thread& other) const; static void yield(); static void sleep(const system_time& xt); }; void swap(thread& lhs,thread& rhs);
thread();
Constructs a boost::thread
instance that refers
to Not-a-Thread.
Nothing
template<typename Callable> thread(Callable func);
Callable
must by
copyable.
func
is copied into
storage managed internally by the thread library, and that copy is
invoked on a newly-created thread of execution. If this invocation
results in an exception being propagated into the internals of the
thread library that is not of type boost::thread_interrupted
,
then std::terminate()
will be called.
*this
refers to the newly created thread of execution.
boost::thread_resource_error
if an error
occurs.
template <class F,class A1,class A2,...> thread(F f,A1 a1,A2 a2,...);
F
and each A
n must by copyable or movable.
*this
refers to the newly created thread of execution.
boost::thread_resource_error
if an error
occurs.
Currently up to nine additional arguments a1
to a9
can be specified
in addition to the function f
.
~thread();
If *this
has an associated thread of execution, calls detach()
.
Destroys *this
.
Nothing.
bool joinable() const;
true
if *this
refers to a thread of execution, false
otherwise.
Nothing
void join();
this->get_id()!=boost::this_thread::get_id()
If *this
refers to a thread of execution, waits for that thread of execution
to complete.
If *this
refers to a thread of execution on entry, that thread of execution
has completed. *this
no longer refers to any thread of execution.
boost::thread_interrupted
if the current
thread of execution is interrupted.
join()
is one of the predefined interruption
points.
bool timed_join(const system_time& wait_until); template<typename TimeDuration> bool timed_join(TimeDuration const& rel_time);
this->get_id()!=boost::this_thread::get_id()
If *this
refers to a thread of execution, waits for that thread of execution
to complete, the time wait_until
has been reach or the specified duration rel_time
has elapsed. If *this
doesn't refer to a thread of execution, returns immediately.
true
if *this
refers to a thread of execution on entry, and that thread of execution
has completed before the call times out, false
otherwise.
If *this
refers to a thread of execution on entry, and timed_join
returns true
, that thread
of execution has completed, and *this
no longer refers to any thread
of execution. If this call to timed_join
returns false
, *this
is unchanged.
boost::thread_interrupted
if the current
thread of execution is interrupted.
timed_join()
is one of the predefined interruption
points.
void detach();
If *this
refers to a thread of execution, that thread of execution becomes
detached, and no longer has an associated boost::thread
object.
*this
no longer refers to any thread of execution.
Nothing
thread::id get_id() const;
If *this
refers to a thread of execution, an instance of boost::thread::id
that represents that
thread. Otherwise returns a default-constructed boost::thread::id
.
Nothing
void interrupt();
If *this
refers to a thread of execution, request that the thread will be
interrupted the next time it enters one of the predefined interruption
points with interruption enabled, or if it is currently
blocked in a call to one of the predefined
interruption points
with interruption enabled .
Nothing
unsigned hardware_concurrency();
The number of hardware threads available on the current system (e.g. number of CPUs or cores or hyperthreading units), or 0 if this information is not available.
Nothing
typedef platform-specific-type native_handle_type; native_handle_type native_handle();
Returns an instance of native_handle_type
that can be used with platform-specific APIs to manipulate the underlying
implementation. If no such instance exists, native_handle()
and native_handle_type
are not present.
Nothing.
void sleep(system_time const& abs_time);
Suspends the current thread until the specified time has been reached.
boost::thread_interrupted
if the current
thread of execution is interrupted.
sleep()
is one of the predefined interruption
points.
void swap(thread& other);
Exchanges the threads of execution associated with *this
and other
, so *this
is associated with the thread of execution associated with other
prior to the call, and vice-versa.
this->get_id()
returns the same value as other.get_id()
prior to the call. other.get_id()
returns the same value as this->get_id()
prior to the call.
Nothing.
#include <boost/thread/thread.hpp> void swap(thread& lhs,thread& rhs);
#include <boost/thread/thread.hpp> class thread::id { public: id(); bool operator==(const id& y) const; bool operator!=(const id& y) const; bool operator<(const id& y) const; bool operator>(const id& y) const; bool operator<=(const id& y) const; bool operator>=(const id& y) const; template<class charT, class traits> friend std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const id& x); };
id();
Constructs a boost::thread::id
instance that represents
Not-a-Thread.
Nothing
bool operator==(const id& y) const;
true
if *this
and y
both represent
the same thread of execution, or both represent Not-a-Thread,
false
otherwise.
Nothing
bool operator!=(const id& y) const;
true
if *this
and y
represent
different threads of execution, or one represents a thread of execution,
and the other represent Not-a-Thread, false
otherwise.
Nothing
bool operator<(const id& y) const;
true
if *this!=y
is true
and the implementation-defined
total order of boost::thread::id
values places *this
before y
, false
otherwise.
Nothing
A boost::thread::id
instance representing
Not-a-Thread will always compare less than
an instance representing a thread of execution.
template<class charT, class traits> friend std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const id& x);
Writes a representation of the boost::thread::id
instance x
to the stream os
, such that the representation
of two instances of boost::thread::id
a
and b
is the same
if a==b
, and different if a!=b
.
os
get_id()
interruption_point()
interruption_requested()
interruption_enabled()
sleep()
yield()
disable_interruption
restore_interruption
at_thread_exit()
#include <boost/thread/thread.hpp> namespace this_thread { thread::id get_id(); }
An instance of boost::thread::id
that represents that
currently executing thread.
boost::thread_resource_error
if an error
occurs.
#include <boost/thread/thread.hpp> namespace this_thread { void interruption_point(); }
Check to see if the current thread has been interrupted.
boost::thread_interrupted
if boost::this_thread::interruption_enabled()
and boost::this_thread::interruption_requested()
both return true
.
#include <boost/thread/thread.hpp> namespace this_thread { bool interruption_requested(); }
true
if interruption
has been requested for the current thread, false
otherwise.
Nothing.
#include <boost/thread/thread.hpp> namespace this_thread { bool interruption_enabled(); }
true
if interruption
has been enabled for the current thread, false
otherwise.
Nothing.
#include <boost/thread/thread.hpp> namespace this_thread { template<typename TimeDuration> void sleep(TimeDuration const& rel_time); }
Suspends the current thread until the specified time has elapsed.
boost::thread_interrupted
if the current
thread of execution is interrupted.
sleep()
is one of the predefined interruption
points.
#include <boost/thread/thread.hpp> namespace this_thread { void yield(); }
Gives up the remainder of the current thread's time slice, to allow other threads to run.
Nothing.
#include <boost/thread/thread.hpp> namespace this_thread { class disable_interruption { public: disable_interruption(); ~disable_interruption(); }; }
boost::this_thread::disable_interruption
disables interruption
for the current thread on construction, and restores the prior interruption
state on destruction. Instances of disable_interruption
cannot be copied or moved.
disable_interruption();
Stores the current state of boost::this_thread::interruption_enabled()
and disables interruption for the current thread.
boost::this_thread::interruption_enabled()
returns false
for
the current thread.
Nothing.
~disable_interruption();
Must be called from the same thread from which *this
was constructed.
Restores the current state of boost::this_thread::interruption_enabled()
for the current thread to that prior to the construction of *this
.
boost::this_thread::interruption_enabled()
for the current thread returns the value stored in the constructor
of *this
.
Nothing.
#include <boost/thread/thread.hpp> namespace this_thread { class restore_interruption { public: explicit restore_interruption(disable_interruption& disabler); ~restore_interruption(); }; }
On construction of an instance of boost::this_thread::restore_interruption
,
the interruption state for the current thread is restored to the interruption
state stored by the constructor of the supplied instance of boost::this_thread::disable_interruption
. When the
instance is destroyed, interruption is again disabled. Instances of restore_interruption
cannot be copied
or moved.
explicit restore_interruption(disable_interruption& disabler);
Must be called from the same thread from which disabler
was constructed.
Restores the current state of boost::this_thread::interruption_enabled()
for the current thread to that prior to the construction of disabler
.
boost::this_thread::interruption_enabled()
for the current thread returns the value stored in the constructor
of disabler
.
Nothing.
~restore_interruption();
Must be called from the same thread from which *this
was constructed.
Disables interruption for the current thread.
boost::this_thread::interruption_enabled()
for the current thread returns false
.
Nothing.
#include <boost/thread/thread.hpp> template<typename Callable> void at_thread_exit(Callable func);
A copy of func
is
placed in thread-specific storage. This copy is invoked when the
current thread exits (even if the thread has been interrupted).
A copy of func
has
been saved for invocation on thread exit.
std::bad_alloc
if memory cannot be allocated
for the copy of the function, boost::thread_resource_error
if any other error occurs within the thread library. Any exception
thrown whilst copying func
into internal storage.
This function is not called if the
thread was terminated forcefully using platform-specific APIs, or
if the thread is terminated due to a call to exit()
, abort()
or std::terminate()
. In particular, returning from
main()
is equivalent to call to exit()
, so will not call any functions
registered with at_thread_exit()
#include <boost/thread/thread.hpp> class thread_group: private noncopyable { public: thread_group(); ~thread_group(); template<typename F> thread* create_thread(F threadfunc); void add_thread(thread* thrd); void remove_thread(thread* thrd); void join_all(); void interrupt_all(); int size() const; };
thread_group
provides for
a collection of threads that are related in some fashion. New threads can
be added to the group with add_thread
and create_thread
member
functions. thread_group
is
not copyable or movable.
~thread_group();
Destroy *this
and delete
all boost::thread
objects in the group.
template<typename F> thread* create_thread(F threadfunc);
Create a new boost::thread
object as-if by
new thread(threadfunc)
and add it to the group.
this->size()
is increased by one, the new thread is running.
A pointer to the new boost::thread
object.
void add_thread(thread* thrd);
The expression delete thrd
is well-formed and will not
result in undefined behaviour.
Take ownership of the boost::thread
object pointed to
by thrd
and add it
to the group.
this->size()
is increased by one.
void remove_thread(thread* thrd);
If thrd
is a member
of the group, remove it without calling delete
.
If thrd
was a member
of the group, this->size()
is decreased by one.
void join_all();
Call join()
on each boost::thread
object in the group.
Every thread in the group has terminated.
Since join()
is one of the predefined interruption
points, join_all()
is also an interruption point.
void interrupt_all();
Call interrupt()
on each boost::thread
object in the group.