Thread Management

| Home | Libraries | People | FAQ | More

## Thread Management

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

- `boost::thread::join()`
- `boost::thread::timed_join()`
- `boost::condition_variable::wait()`
- `boost::condition_variable::timed_wait()`
- `boost::condition_variable_any::wait()`
- `boost::condition_variable_any::timed_wait()`
- `boost::thread::sleep()`
- `boost::this_thread::sleep()`
- `boost::this_thread::interruption_point()`

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

### Class `thread`

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

#### Default Constructor

    thread();

Effects:

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

Throws:

  Nothing

#### Thread Constructor

    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.

Postconditions:

  `*this` refers to the newly created thread of execution.

Throws:

  `boost::thread_resource_error` if an error occurs.

#### Thread Destructor

    ~thread();

Effects:

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

Throws:

  Nothing.

#### Member function `joinable()`

    bool joinable() const;

Returns:

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

Throws:

  Nothing

#### Member function `join()`

    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.

#### Member function `timed_join()`

    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.

#### Member function `detach()`

    void detach();

Effects:

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

Postconditions:

  `*this` no longer refers to any thread of execution.

Throws:

  Nothing

#### Member function `get_id()`

    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

#### Member function `interrupt()`

    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

#### Static member function `hardware_concurrency()`

    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

#### `operator==`

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

Returns:

  `get_id()==other.get_id()`

#### `operator!=`

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

Returns:

  `get_id()!=other.get_id()`

#### Static member function `sleep()`

    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.

#### Static member function `yield()`

    void yield();

Effects:

  See `boost::this_thread::yield()`.

#### Class `boost::thread::id`

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

##### Default constructor

    id();

Effects:

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

Throws:

  Nothing

##### `operator==`

    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

##### `operator!=`

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

Returns:

  `true` if `*this` and `y` represent the different threads of execution, or one represents a thread of execution, and the other represent Not-a-Thread, `false` otherwise.

Throws:

  Nothing

##### `operator<`

    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.

##### `operator>`

    bool operator>(const id& y) const;

Returns:

  `y<*this`

Throws:

  Nothing

##### `operator>=`

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

Returns:

  `!(y<*this)`

Throws:

  Nothing

##### `operator>=`

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

Returns:

  `!(*this<y)`

Throws:

  Nothing

##### Friend `operator<<`

    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`

### Namespace `this_thread`

#### Non-member function `get_id()`

    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.

#### Non-member function `interruption_point()`

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

#### Non-member function `interruption_requested()`

    namespace this_thread
    {
        bool interruption_requested();
    }

Returns:

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

Throws:

  Nothing.

#### Non-member function `interruption_enabled()`

    namespace this_thread
    {
        bool interruption_enabled();
    }

Returns:

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

Throws:

  Nothing.

#### Non-member function `sleep()`

    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_interrupted` if the current thread of execution is interrupted.

Notes:

  `sleep()` is one of the predefined interruption points.

#### Non-member function `yield()`

    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.

#### Class `disable_interruption`

    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.

##### Constructor

    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.

##### Destructor

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

#### Class `restore_interruption`

    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.

##### Constructor

    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.

##### Destructor

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

#### Non-member function template `at_thread_exit()`

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

Effects:

  A copy of `func` is taken and stored to in thread-specific storage. This copy is invoked when the current thread exits.

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.

### Class `thread_group`

    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.

#### Constructor

    thread_group();

Effects:

  Create a new thread group with no threads.

#### Destructor

    ~thread_group();

Effects:

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

#### Member function `create_thread()`

    thread* create_thread(const function0<void>& 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.

#### Member function `add_thread()`

    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.

#### Member function `remove_thread()`

    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.

#### Member function `join_all()`

    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.

#### Member function `interrupt_all()`

    void interrupt_all();

Effects:

  Call `interrupt()` on each `boost::thread` object in the group.

#### Member function `size()`

    int size();

Returns:

  The number of threads in the group.

Throws:

  Nothing.