Synopsis
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(); }
Launching threads
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 using boost::bind:
void find_the_question(int the_answer); boost::thread deep_thought_2(boost::bind(find_the_question,42));
Joining and detaching
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.
Interruption
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().
Predefined Interruption Points
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:
Thread IDs
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.
- Default Constructor
- Thread Constructor
- Thread Destructor
- Member function
joinable() - Member function
join() - Member
function
timed_join() - Member function
detach() - Member function
get_id() - Member
function
interrupt() -
Static member function
hardware_concurrency() -
operator== -
operator!= - Static member
function
sleep() - Static member
function
yield() - Class
boost::thread::id
class thread { public: thread(); ~thread(); template <class F> explicit thread(F f); 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); };
thread();
- Effects:
Constructs a
boost::threadinstance that refers to Not-a-Thread.- Throws:
Nothing
template<typename Callable> thread(Callable func);
- Preconditions:
Callablemust by copyable.- Effects:
funcis copied into storage managed internally by the thread library, and that copy is invoked on a newly-created thread of execution.- Postconditions:
*thisrefers to the newly created thread of execution.- Throws:
boost::thread_resource_errorif an error occurs.
~thread();
- Effects:
If
*thishas an associated thread of execution, callsdetach(). Destroys*this.- Throws:
Nothing.
bool joinable() const;
- Returns:
trueif*thisrefers to a thread of execution,falseotherwise.- Throws:
Nothing
void join();
- Preconditions:
this->get_id()!=boost::this_thread::get_id()- Effects:
If
*thisrefers to a thread of execution, waits for that thread of execution to complete.- Postconditions:
If
*thisrefers to a thread of execution on entry, that thread of execution has completed.*thisno longer refers to any thread of execution.- Throws:
boost::thread_interruptedif the current thread of execution is interrupted.- Notes:
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);
- Preconditions:
this->get_id()!=boost::this_thread::get_id()- Effects:
If
*thisrefers to a thread of execution, waits for that thread of execution to complete, the timewait_untilhas been reach or the specified durationrel_timehas elapsed. If*thisdoesn't refer to a thread of execution, returns immediately.- Returns:
trueif*thisrefers to a thread of execution on entry, and that thread of execution has completed before the call times out,falseotherwise.- Postconditions:
If
*thisrefers to a thread of execution on entry, andtimed_joinreturnstrue, that thread of execution has completed, and*thisno longer refers to any thread of execution. If this call totimed_joinreturnsfalse,*thisis unchanged.- Throws:
boost::thread_interruptedif the current thread of execution is interrupted.- Notes:
timed_join()is one of the predefined interruption points.
void detach();
- Effects:
If
*thisrefers to a thread of execution, that thread of execution becomes detached, and longer has an associatedboost::threadobject.- Postconditions:
*thisno longer refers to any thread of execution.- Throws:
Nothing
thread::id get_id() const;
- Returns:
If
*thisrefers to a thread of execution, an instance ofboost::thread::idthat represents that thread. Otherwise returns a default-constructedboost::thread::id.- Throws:
Nothing
void interrupt();
- Effects:
If
*thisrefers 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 .- Throws:
Nothing
unsigned hardware_concurrency();
- Returns:
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.
- Throws:
Nothing
void sleep(system_time const& abs_time);
- Effects:
Suspends the current thread until the specified time has been reached.
- Throws:
boost::thread_interruptedif the current thread of execution is interrupted.- Notes:
sleep()is one of the predefined interruption points.
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();
- Effects:
Constructs a
boost::thread::idinstance that represents Not-a-Thread.- Throws:
Nothing
bool operator==(const id& y) const;
- Returns:
trueif*thisandyboth represent the same thread of execution, or both represent Not-a-Thread,falseotherwise.- Throws:
Nothing
bool operator!=(const id& y) const;
- Returns:
trueif*thisandyrepresent the different threads of execution, or one represents a thread of execution, and the other represent Not-a-Thread,falseotherwise.- Throws:
Nothing
bool operator<(const id& y) const;
- Returns:
trueif*this!=yistrueand the implementation-defined total order ofboost::thread::idvalues places*thisbeforey,falseotherwise.- Throws:
Nothing
- Note:
A
boost::thread::idinstance 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);
- Effects:
Writes a representation of the
boost::thread::idinstancexto the streamos, such that the representation of two instances ofboost::thread::idaandbis the same ifa==b, and different ifa!=b.- Returns:
os
- Non-member
function
get_id() -
Non-member function
interruption_point() -
Non-member function
interruption_requested() -
Non-member function
interruption_enabled() - Non-member
function
sleep() - Non-member
function
yield() -
Class
disable_interruption -
Class
restore_interruption -
Non-member function template
at_thread_exit()
namespace this_thread { thread::id get_id(); }
- Returns:
An instance of
boost::thread::idthat represents that currently executing thread.- Throws:
boost::thread_resource_errorif an error occurs.
namespace this_thread { void interruption_point(); }
- Effects:
Check to see if the current thread has been interrupted.
- Throws:
boost::thread_interruptedifboost::this_thread::interruption_enabled()andboost::this_thread::interruption_requested()both returntrue.
namespace this_thread { bool interruption_requested(); }
- Returns:
trueif interruption has been requested for the current thread,falseotherwise.- Throws:
Nothing.
namespace this_thread { bool interruption_enabled(); }
- Returns:
trueif interruption has been enabled for the current thread,falseotherwise.- Throws:
Nothing.
namespace this_thread { template<typename TimeDuration> void sleep(TimeDuration const& rel_time); }
- Effects:
Suspends the current thread until the specified time has elapsed.
- Throws:
boost::thread_interruptedif the current thread of execution is interrupted.- Notes:
sleep()is one of the predefined interruption points.
namespace this_thread { void yield(); }
- Effects:
Gives up the remainder of the current thread's time slice, to allow other threads to run.
- Throws:
Nothing.
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();
- Effects:
Stores the current state of
boost::this_thread::interruption_enabled()and disables interruption for the current thread.- Postconditions:
boost::this_thread::interruption_enabled()returnsfalsefor the current thread.- Throws:
Nothing.
~disable_interruption();
- Preconditions:
Must be called from the same thread from which
*thiswas constructed.- Effects:
Restores the current state of
boost::this_thread::interruption_enabled()for the current thread to that prior to the construction of*this.- Postconditions:
boost::this_thread::interruption_enabled()for the current thread returns the value stored in the constructor of*this.- Throws:
Nothing.
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);
- Preconditions:
Must be called from the same thread from which
disablerwas constructed.- Effects:
Restores the current state of
boost::this_thread::interruption_enabled()for the current thread to that prior to the construction ofdisabler.- Postconditions:
boost::this_thread::interruption_enabled()for the current thread returns the value stored in the constructor ofdisabler.- Throws:
Nothing.
~restore_interruption();
- Preconditions:
Must be called from the same thread from which
*thiswas constructed.- Effects:
Disables interruption for the current thread.
- Postconditions:
boost::this_thread::interruption_enabled()for the current thread returnsfalse.- Throws:
Nothing.
template<typename Callable> void at_thread_exit(Callable func);
- Effects:
A copy of
funcis taken and stored to in thread-specific storage. This copy is invoked when the current thread exits.- Postconditions:
A copy of
funchas been saved for invocation on thread exit.- Throws:
std::bad_allocif memory cannot be allocated for the copy of the function,boost::thread_resource_errorif any other error occurs within the thread library. Any exception thrown whilst copyingfuncinto internal storage.
class thread_group: private noncopyable { public: thread_group(); ~thread_group(); thread* create_thread(const function0<void>& 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();
- Effects:
Destroy
*thisanddeleteallboost::threadobjects in the group.
thread* create_thread(const function0<void>& threadfunc);
- Effects:
Create a new
boost::threadobject as-if bynew thread(threadfunc)and add it to the group.- Postcondition:
this->size()is increased by one, the new thread is running.- Returns:
A pointer to the new
boost::threadobject.
void add_thread(thread* thrd);
- Precondition:
The expression
delete thrdis well-formed and will not result in undefined behaviour.- Effects:
Take ownership of the
boost::threadobject pointed to bythrdand add it to the group.- Postcondition:
this->size()is increased by one.
void remove_thread(thread* thrd);
- Effects:
If
thrdis a member of the group, remove it without callingdelete.- Postcondition:
If
thrdwas a member of the group,this->size()is decreased by one.
void join_all();
- Effects:
Call
join()on eachboost::threadobject in the group.- Postcondition:
Every thread in the group has terminated.
- Note:
Since
join()is one of the predefined interruption points,join_all()is also an interruption point.
void interrupt_all();
- Effects:
Call
interrupt()on eachboost::threadobject in the group.
