Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Thread Management

Class thread
Namespace this_thread
Class thread_group

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();
}

[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.]

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 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.

Exceptions in thread functions

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.

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.

Using native interfaces with Boost.Thread resources

boost::thread class has members native_handle_type and native_handle providing access to the underlying native handle.

This native handle can be used to change for example the scheduling.

In general, it is not safe to use this handle with operations that can conflict with the ones provided by Boost.Thread. An example of bad usage could be detaching a thread directly as it will not change the internals of the boost::thread instance, so for example the joinable function will continue to return true, while the native thread is no more joinable.

thread t(fct);
thread::native_handle_type hnd=t.native_handle();
pthread_detach(hnd);
assert(t.joinable());

Using Boost.Thread interfaces in a native thread

Any thread of execution created using the native interface is called a native thread in this documentation.

The first example of a native thread of execution is the main thread.

The user can access to some synchronization functions related to the native current thread using the boost::this_thread yield, sleep, functions.

int main() {
  // ... 
  boost::this_thread::sleep();
  // ... 
}

Of course all the synchronization facilities provided by Boost.Thread are also available on native threads.

The boost::this_thread interrupt related functions behave in a degraded mode when called from a thread created using the native interface, i.e. boost::this_thread::interruption_enabled() returns false. As consequence the use of boost::this_thread::disable_interruption and boost::this_thread::restore_interruption will do nothing and calls to boost::this_thread::interrupt_point() will be just ignored.

As the single way to interrupt a thread is through a boost::thread instance, interruption_request() wiil returns false for the native threads.

#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);
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t);
thread();

Effects:

Constructs a boost::thread instance that refers to Not-a-Thread.

Throws:

Nothing

thread(detail::thread_move_t<thread> other);

Effects:

Transfers ownership of the thread managed by other (if any) to the newly constructed boost::thread instance.

Postconditions:

other->get_id()==thread::id()

Throws:

Nothing

thread& operator=(detail::thread_move_t<thread> other);

Effects:

Transfers ownership of the thread managed by other (if any) to *this. If there was a thread previously associated with *this then that thread is detached.

Postconditions:

other->get_id()==thread::id()

Throws:

Nothing

template<typename Callable>
thread(Callable func);

Preconditions:

Callable must by copyable.

Effects:

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.

Postconditions:

*this refers to the newly created thread of execution.

Throws:

boost::thread_resource_error if an error occurs.

template <class F,class A1,class A2,...>
thread(F f,A1 a1,A2 a2,...);

Preconditions:

F and each An must by copyable or movable.

Effects:

As if thread(boost::bind(f,a1,a2,...)). Consequently, f and each an are copied into internal storage for access by the new thread.

Postconditions:

*this refers to the newly created thread of execution.

Throws:

boost::thread_resource_error if an error occurs.

Note:

Currently up to nine additional arguments a1 to a9 can be specified in addition to the function f.

~thread();

Effects:

If *this has an associated thread of execution, calls detach(). Destroys *this.

Throws:

Nothing.

bool joinable() const;

Returns:

true if *this refers to a thread of execution, false otherwise.

Throws:

Nothing

void join();

Preconditions:

this->get_id()!=boost::this_thread::get_id()

Effects:

If *this refers to a thread of execution, waits for that thread of execution to complete.

Postconditions:

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.

Throws:

boost::thread_interrupted if 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 *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.

Returns:

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.

Postconditions:

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.

Throws:

boost::thread_interrupted if the current thread of execution is interrupted.

Notes:

timed_join() is one of the predefined interruption points.

void detach();

Effects:

If *this refers to a thread of execution, that thread of execution becomes detached, and no longer has an associated boost::thread object.

Postconditions:

*this no longer refers to any thread of execution.

Throws:

Nothing

thread::id get_id() const;

Returns:

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.

Throws:

Nothing

void interrupt();

Effects:

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 .

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

typedef platform-specific-type native_handle_type;
native_handle_type native_handle();

Effects:

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.

Throws:

Nothing.

bool operator==(const thread& other) const;

Returns:

get_id()==other.get_id()

bool operator!=(const thread& other) const;

Returns:

get_id()!=other.get_id()

void sleep(system_time const& abs_time);

Effects:

Suspends the current thread until the specified time has been reached.

Throws:

boost::thread_interrupted if the current thread of execution is interrupted.

Notes:

sleep() is one of the predefined interruption points.

void swap(thread& other);

Effects:

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.

Postconditions:

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.

Throws:

Nothing.

#include <boost/thread/thread.hpp>

void swap(thread& lhs,thread& rhs);

Effects:

lhs.swap(rhs).

#include <boost/thread/thread.hpp>

detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)

Returns:

t.

Enables moving thread objects. e.g.

extern void some_func();
boost::thread t(some_func);
boost::thread t2(boost::move(t)); // transfer thread from t to t2
#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();

Effects:

Constructs a boost::thread::id instance that represents Not-a-Thread.

Throws:

Nothing

bool operator==(const id& y) const;

Returns:

true if *this and y both represent the same thread of execution, or both represent Not-a-Thread, false otherwise.

Throws:

Nothing

bool operator!=(const id& y) const;

Returns:

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.

Throws:

Nothing

bool operator<(const id& y) const;

Returns:

true if *this!=y is true and the implementation-defined total order of boost::thread::id values places *this before y, false otherwise.

Throws:

Nothing

Note:

A boost::thread::id instance representing Not-a-Thread will always compare less than an instance representing a thread of execution.

bool operator>(const id& y) const;

Returns:

y<*this

Throws:

Nothing

bool operator<=(const id& y) const;

Returns:

!(y<*this)

Throws:

Nothing

bool operator>=(const id& y) const;

Returns:

!(*this<y)

Throws:

Nothing

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::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.

Returns:

os

#include <boost/thread/thread.hpp>

namespace this_thread
{
    thread::id get_id();
}

Returns:

An instance of boost::thread::id that represents that currently executing thread.

Throws:

boost::thread_resource_error if an error occurs.

#include <boost/thread/thread.hpp>

namespace this_thread
{
    void interruption_point();
}

Effects:

Check to see if the current thread has been interrupted.

Throws:

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();
}

Returns:

true if interruption has been requested for the current thread, false otherwise.

Throws:

Nothing.

#include <boost/thread/thread.hpp>

namespace this_thread
{
    bool interruption_enabled();
}

Returns:

true if interruption has been enabled for the current thread, false otherwise.

Throws:

Nothing.

#include <boost/thread/thread.hpp>

namespace this_thread
{
    template<typename TimeDuration>
    void sleep(TimeDuration const& rel_time);
    void sleep(system_time const& abs_time)
}

Effects:

Suspends the current thread until the time period specified by rel_time has elapsed or the time point specified by abs_time has been reached.

Throws:

boost::thread_interrupted if the current thread of execution is interrupted.

Notes:

sleep() is one of the predefined interruption points.

#include <boost/thread/thread.hpp>

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.

#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();

Effects:

Stores the current state of boost::this_thread::interruption_enabled() and disables interruption for the current thread.

Postconditions:

boost::this_thread::interruption_enabled() returns false for the current thread.

Throws:

Nothing.

~disable_interruption();

Preconditions:

Must be called from the same thread from which *this was 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.

#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);

Preconditions:

Must be called from the same thread from which disabler was constructed.

Effects:

Restores the current state of boost::this_thread::interruption_enabled() for the current thread to that prior to the construction of disabler.

Postconditions:

boost::this_thread::interruption_enabled() for the current thread returns the value stored in the constructor of disabler.

Throws:

Nothing.

~restore_interruption();

Preconditions:

Must be called from the same thread from which *this was constructed.

Effects:

Disables interruption for the current thread.

Postconditions:

boost::this_thread::interruption_enabled() for the current thread returns false.

Throws:

Nothing.

#include <boost/thread/thread.hpp>

template<typename Callable>
void at_thread_exit(Callable func);

Effects:

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).

Postconditions:

A copy of func has been saved for invocation on thread exit.

Throws:

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.

Note:

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();

Effects:

Create a new thread group with no threads.

~thread_group();

Effects:

Destroy *this and delete all boost::thread objects in the group.

template<typename F>
thread* create_thread(F threadfunc);

Effects:

Create a new boost::thread object as-if by new 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::thread object.

void add_thread(thread* thrd);

Precondition:

The expression delete thrd is well-formed and will not result in undefined behaviour.

Effects:

Take ownership of the boost::thread object pointed to by thrd and add it to the group.

Postcondition:

this->size() is increased by one.

void remove_thread(thread* thrd);

Effects:

If thrd is a member of the group, remove it without calling delete.

Postcondition:

If thrd was a member of the group, this->size() is decreased by one.

void join_all();

Effects:

Call join() on each boost::thread object 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 each boost::thread object in the group.

int size();

Returns:

The number of threads in the group.

Throws:

Nothing.


PrevUpHomeNext