Synchronization

| Home | Libraries | People | FAQ | More

## Synchronization

### Mutex Concepts

A mutex object facilitates protection against data races and allows thread-safe synchronization of data between threads. A thread obtains ownership of a mutex object by calling one of the lock functions and relinquishes ownership by calling the corresponding unlock function. Mutexes may be either recursive or non-recursive, and may grant simultaneous ownership to one or many threads. Boost.Thread supplies recursive and non-recursive mutexes with exclusive ownership semantics, along with a shared ownership (multiple-reader / single-writer) mutex.

Boost.Thread supports four basic concepts for lockable objects: `Lockable`, `TimedLockable`, `SharedLockable` and `UpgradeLockable`. Each mutex type implements one or more of these concepts, as do the various lock types.

#### `Lockable` Concept

The `Lockable` concept models exclusive ownership. A type that implements the `Lockable` concept shall provide the following member functions:

- `void lock();`
- `bool try_lock();`
- `void unlock();`

Lock ownership acquired through a call to `lock()` or `try_lock()` must be released through a call to `unlock()`.

##### `void lock()`

Effects:

  The current thread blocks until ownership can be obtained for the current thread.

Postcondition:

  The current thread owns `*this`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `bool try_lock()`

Effects:

  Attempt to obtain ownership for the current thread without blocking.

Returns:

  `true` if ownership was obtained for the current thread, `false` otherwise.

Postcondition:

  If the call returns `true`, the current thread owns the `*this`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `void unlock()`

Precondition:

  The current thread owns `*this`.

Effects:

  Releases ownership by the current thread.

Postcondition:

  The current thread no longer owns `*this`.

Throws:

  Nothing

#### `TimedLockable` Concept

The `TimedLockable` concept refines the `Lockable` concept to add support for timeouts when trying to acquire the lock.

A type that implements the `TimedLockable` concept shall meet the requirements of the `Lockable` concept. In addition, the following member functions must be provided:

- `bool timed_lock(boost::system_time const& abs_time);`
- `template<typename DurationType> bool timed_lock(DurationType const& rel_time);`

Lock ownership acquired through a call to `timed_lock()` must be released through a call to `unlock()`.

##### `bool timed_lock(boost::system_time const& abs_time)`

Effects:

  Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is reached. If the specified time has already passed, behaves as `try_lock()`.

Returns:

  `true` if ownership was obtained for the current thread, `false` otherwise.

Postcondition:

  If the call returns `true`, the current thread owns `*this`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `template<typename DurationType> bool timed_lock(DurationType const& rel_time)`

Effects:

  As-if `timed_lock(boost::get_system_time()+rel_time)`.

#### `SharedLockable` Concept

The `SharedLockable` concept is a refinement of the `TimedLockable` concept that allows for shared ownership as well as exclusive ownership. This is the standard multiple-reader / single-write model: at most one thread can have exclusive ownership, and if any thread does have exclusive ownership, no other threads can have shared or exclusive ownership. Alternatively, many threads may have shared ownership.

For a type to implement the `SharedLockable` concept, as well as meeting the requirements of the `TimedLockable` concept, it must also provide the following member functions:

- `void lock_shared();`
- `bool try_lock_shared();`
- `bool unlock_shared();`
- `bool timed_lock_shared(boost::system_time const& abs_time);`

Lock ownership acquired through a call to `lock_shared()`, `try_lock_shared()` or `timed_lock_shared()` must be released through a call to `unlock_shared()`.

##### `void lock_shared()`

Effects:

  The current thread blocks until shared ownership can be obtained for the current thread.

Postcondition:

  The current thread has shared ownership of `*this`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `bool try_lock_shared()`

Effects:

  Attempt to obtain shared ownership for the current thread without blocking.

Returns:

  `true` if shared ownership was obtained for the current thread, `false` otherwise.

Postcondition:

  If the call returns `true`, the current thread has shared ownership of `*this`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `bool timed_lock_shared(boost::system_time const& abs_time)`

Effects:

  Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the specified time is reached. If the specified time has already passed, behaves as `try_lock_shared()`.

Returns:

  `true` if shared ownership was acquired for the current thread, `false` otherwise.

Postcondition:

  If the call returns `true`, the current thread has shared ownership of `*this`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `void unlock_shared()`

Precondition:

  The current thread has shared ownership of `*this`.

Effects:

  Releases shared ownership of `*this` by the current thread.

Postcondition:

  The current thread no longer has shared ownership of `*this`.

Throws:

  Nothing

#### `UpgradeLockable` Concept

The `UpgradeLockable` concept is a refinement of the `SharedLockable` concept that allows for upgradable ownership as well as shared ownership and exclusive ownership. This is an extension to the multiple-reader / single-write model provided by the `SharedLockable` concept: a single thread may have upgradable ownership at the same time as others have shared ownership. The thread with upgradable ownership may at any time attempt to upgrade that ownership to exclusive ownership. If no other threads have shared ownership, the upgrade is completed immediately, and the thread now has exclusive ownership, which must be relinquished by a call to `unlock()`, just as if it had been acquired by a call to `lock()`.

If a thread with upgradable ownership tries to upgrade whilst other threads have shared ownership, the attempt will fail and the thread will block until exclusive ownership can be acquired.

Ownership can also be downgraded as well as upgraded: exclusive ownership of an implementation of the `UpgradeLockable` concept can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be downgraded to plain shared ownership.

For a type to implement the `UpgradeLockable` concept, as well as meeting the requirements of the `SharedLockable` concept, it must also provide the following member functions:

- `void lock_upgrade();`
- `bool unlock_upgrade();`
- `void unlock_upgrade_and_lock();`
- `void unlock_and_lock_upgrade();`
- `void unlock_upgrade_and_lock_shared();`

Lock ownership acquired through a call to `lock_upgrade()` must be released through a call to `unlock_upgrade()`. If the ownership type is changed through a call to one of the `unlock_xxx_and_lock_yyy()` functions, ownership must be released through a call to the unlock function corresponding to the new level of ownership.

##### `void lock_upgrade()`

Effects:

  The current thread blocks until upgrade ownership can be obtained for the current thread.

Postcondition:

  The current thread has upgrade ownership of `*this`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `void unlock_upgrade()`

Precondition:

  The current thread has upgrade ownership of `*this`.

Effects:

  Releases upgrade ownership of `*this` by the current thread.

Postcondition:

  The current thread no longer has upgrade ownership of `*this`.

Throws:

  Nothing

##### `void unlock_upgrade_and_lock()`

Precondition:

  The current thread has upgrade ownership of `*this`.

Effects:

  Atomically releases upgrade ownership of `*this` by the current thread and acquires exclusive ownership of `*this`. If any other threads have shared ownership, blocks until exclusive ownership can be acquired.

Postcondition:

  The current thread has exclusive ownership of `*this`.

Throws:

  Nothing

##### `void unlock_upgrade_and_lock_shared()`

Precondition:

  The current thread has upgrade ownership of `*this`.

Effects:

  Atomically releases upgrade ownership of `*this` by the current thread and acquires shared ownership of `*this` without blocking.

Postcondition:

  The current thread has shared ownership of `*this`.

Throws:

  Nothing

##### `void unlock_and_lock_upgrade()`

Precondition:

  The current thread has exclusive ownership of `*this`.

Effects:

  Atomically releases exclusive ownership of `*this` by the current thread and acquires upgrade ownership of `*this` without blocking.

Postcondition:

  The current thread has upgrade ownership of `*this`.

Throws:

  Nothing

### Lock Types

#### Class template `lock_guard`

    template<typename Lockable>
    class lock_guard
    {
    public:
        explicit lock_guard(Lockable& m_);
        lock_guard(Lockable& m_,boost::adopt_lock_t);

        ~lock_guard();
    };

`boost::lock_guard` is very simple: on construction it acquires ownership of the implementation of the `Lockable` concept supplied as the constructor parameter. On destruction, the ownership is released. This provides simple RAII-style locking of a `Lockable` object, to facilitate exception-safe locking and unlocking. In addition, the `lock_guard(Lockable & m,boost::adopt_lock_t)` constructor allows the `boost::lock_guard` object to take ownership of a lock already held by the current thread.

##### `lock_guard(Lockable & m)`

Effects:

  Stores a reference to `m`. Invokes `m.lock()`.

Throws:

  Any exception thrown by the call to `m.lock()`.

##### `lock_guard(Lockable & m,boost::adopt_lock_t)`

Precondition:

  The current thread owns a lock on `m` equivalent to one obtained by a call to `m.lock()`.

Effects:

  Stores a reference to `m`. Takes ownership of the lock state of `m`.

Throws:

  Nothing.

##### `~lock_guard()`

Effects:

  Invokes `m.unlock()` on the `Lockable` object passed to the constructor.

Throws:

  Nothing.

#### Class template `unique_lock`

    template<typename Lockable>
    class unique_lock
    {
    public:
        explicit unique_lock(Lockable& m_);
        unique_lock(Lockable& m_,adopt_lock_t);
        unique_lock(Lockable& m_,defer_lock_t);
        unique_lock(Lockable& m_,try_to_lock_t);
        unique_lock(Lockable& m_,system_time const& target_time);

        ~unique_lock();

        unique_lock(detail::thread_move_t<unique_lock<Lockable> > other);
        unique_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);

        operator detail::thread_move_t<unique_lock<Lockable> >();
        detail::thread_move_t<unique_lock<Lockable> > move();
        unique_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
        unique_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);

        void swap(unique_lock& other);
        void swap(detail::thread_move_t<unique_lock<Lockable> > other);

        void lock();
        bool try_lock();

        template<typename TimeDuration>
        bool timed_lock(TimeDuration const& relative_time);
        bool timed_lock(::boost::system_time const& absolute_time);

        void unlock();

        bool owns_lock() const;
        operator unspecified-bool-type() const;
        bool operator!() const;

        Lockable* mutex() const;
        Lockable* release();
    };

`boost::unique_lock` is more complex than `boost::lock_guard`: not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the `lock()` member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a timeout. Consequently, `unlock()` is only called in the destructor if the lock object has locked the `Lockable` object, or otherwise adopted a lock on the `Lockable` object.

Specializations of `boost::unique_lock` model the `TimedLockable` concept if the supplied `Lockable` type itself models `TimedLockable` concept (e.g. `boost::unique_lock<boost::timed_mutex>`), or the `Lockable` concept otherwise (e.g. `boost::unique_lock<boost::mutex>`).

An instance of `boost::unique_lock` is said to own the lock state of a `Lockable` `m` if `mutex()` returns a pointer to `m` and `owns_lock()` returns `true`. If an object that owns the lock state of a `Lockable` object is destroyed, then the destructor will invoke `mutex()->unlock()`.

The member functions of `boost::unique_lock` are not thread-safe. In particular, `boost::unique_lock` is intended to model the ownership of a `Lockable` object by a particular thread, and the member functions that release ownership of the lock state (including the destructor) must be called by the same thread that acquired ownership of the lock state.

##### `unique_lock(Lockable & m)`

Effects:

  Stores a reference to `m`. Invokes `m.lock()`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Any exception thrown by the call to `m.lock()`.

##### `unique_lock(Lockable & m,boost::adopt_lock_t)`

Precondition:

  The current thread owns an exclusive lock on `m`.

Effects:

  Stores a reference to `m`. Takes ownership of the lock state of `m`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `unique_lock(Lockable & m,boost::defer_lock_t)`

Effects:

  Stores a reference to `m`.

Postcondition:

  `owns_lock()` returns `false`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `unique_lock(Lockable & m,boost::try_to_lock_t)`

Effects:

  Stores a reference to `m`. Invokes `m.try_lock()`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `try_lock()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Nothing.

##### `unique_lock(Lockable & m,boost::system_time const& abs_time)`

Effects:

  Stores a reference to `m`. Invokes `m.timed_lock(abs_time)`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `timed_lock()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Any exceptions thrown by the call to `m.timed_lock(abs_time)`.

##### `~unique_lock()`

Effects:

  Invokes `mutex()``->` `unlock()` if `owns_lock()` returns `true`.

Throws:

  Nothing.

##### `bool owns_lock() const`

Returns:

  `true` if the `*this` owns the lock on the `Lockable` object associated with `*this`.

Throws:

  Nothing.

##### `Lockable* mutex() const`

Returns:

  A pointer to the `Lockable` object associated with `*this`, or `NULL` if there is no such object.

Throws:

  Nothing.

##### `operator unspecified-bool-type() const`

Returns:

  If `owns_lock()` would return `true`, a value that evaluates to `true` in boolean contexts, otherwise a value that evaluates to `false` in boolean contexts.

Throws:

  Nothing.

##### `bool operator!() const`

Returns:

  `!` `owns_lock()`.

Throws:

  Nothing.

##### `Lockable* release()`

Effects:

  The association between `*this` and the `Lockable` object is removed, without affecting the lock state of the `Lockable` object. If `owns_lock()` would have returned `true`, it is the responsibility of the calling code to ensure that the `Lockable` is correctly unlocked.

Returns:

  A pointer to the `Lockable` object associated with `*this` at the point of the call, or `NULL` if there is no such object.

Throws:

  Nothing.

Postcondition:

  `*this` is no longer associated with any `Lockable` object. `mutex()` returns `NULL` and `owns_lock()` returns `false`.

#### Class template `shared_lock`

    template<typename Lockable>
    class shared_lock
    {
    public:
        explicit shared_lock(Lockable& m_);
        shared_lock(Lockable& m_,adopt_lock_t);
        shared_lock(Lockable& m_,defer_lock_t);
        shared_lock(Lockable& m_,try_to_lock_t);
        shared_lock(Lockable& m_,system_time const& target_time);
        shared_lock(detail::thread_move_t<shared_lock<Lockable> > other);
        shared_lock(detail::thread_move_t<unique_lock<Lockable> > other);
        shared_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);

        ~shared_lock();

        operator detail::thread_move_t<shared_lock<Lockable> >();
        detail::thread_move_t<shared_lock<Lockable> > move();

        shared_lock& operator=(detail::thread_move_t<shared_lock<Lockable> > other);
        shared_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
        shared_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
        void swap(shared_lock& other);

        void lock();
        bool try_lock();
        bool timed_lock(boost::system_time const& target_time);
        void unlock();

        operator unspecified-bool-type() const;
        bool operator!() const;
        bool owns_lock() const;
    };

Like `boost::unique_lock`, `boost::shared_lock` models the `Lockable` concept, but rather than acquiring unique ownership of the supplied `Lockable` object, locking an instance of `boost::shared_lock` acquires shared ownership.

Like `boost::unique_lock`, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the `lock()` member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a timeout. Consequently, `unlock()` is only called in the destructor if the lock object has locked the `Lockable` object, or otherwise adopted a lock on the `Lockable` object.

An instance of `boost::shared_lock` is said to own the lock state of a `Lockable` `m` if `mutex()` returns a pointer to `m` and `owns_lock()` returns `true`. If an object that owns the lock state of a `Lockable` object is destroyed, then the destructor will invoke `mutex()->unlock_shared()`.

The member functions of `boost::shared_lock` are not thread-safe. In particular, `boost::shared_lock` is intended to model the shared ownership of a `Lockable` object by a particular thread, and the member functions that release ownership of the lock state (including the destructor) must be called by the same thread that acquired ownership of the lock state.

##### `shared_lock(Lockable & m)`

Effects:

  Stores a reference to `m`. Invokes `m.lock_shared()`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Any exception thrown by the call to `m.lock_shared()`.

##### `shared_lock(Lockable & m,boost::adopt_lock_t)`

Precondition:

  The current thread owns an exclusive lock on `m`.

Effects:

  Stores a reference to `m`. Takes ownership of the lock state of `m`.

Postcondition:

  `owns_lock()` returns `true`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `shared_lock(Lockable & m,boost::defer_lock_t)`

Effects:

  Stores a reference to `m`.

Postcondition:

  `owns_lock()` returns `false`. `mutex()` returns `&m`.

Throws:

  Nothing.

##### `shared_lock(Lockable & m,boost::try_to_lock_t)`

Effects:

  Stores a reference to `m`. Invokes `m.try_lock_shared()`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `try_lock_shared()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Nothing.

##### `shared_lock(Lockable & m,boost::system_time const& abs_time)`

Effects:

  Stores a reference to `m`. Invokes `m.timed_lock(abs_time)`, and takes ownership of the lock state if the call returns `true`.

Postcondition:

  `mutex()` returns `&m`. If the call to `timed_lock_shared()` returned `true`, then `owns_lock()` returns `true`, otherwise `owns_lock()` returns `false`.

Throws:

  Any exceptions thrown by the call to `m.timed_lock(abs_time)`.

##### `~shared_lock()`

Effects:

  Invokes `mutex()``->` `unlock_shared()` if `owns_lock()` returns `true`.

Throws:

  Nothing.

##### `bool owns_lock() const`

Returns:

  `true` if the `*this` owns the lock on the `Lockable` object associated with `*this`.

Throws:

  Nothing.

##### `Lockable* mutex() const`

Returns:

  A pointer to the `Lockable` object associated with `*this`, or `NULL` if there is no such object.

Throws:

  Nothing.

##### `operator unspecified-bool-type() const`

Returns:

  If `owns_lock()` would return `true`, a value that evaluates to `true` in boolean contexts, otherwise a value that evaluates to `false` in boolean contexts.

Throws:

  Nothing.

##### `bool operator!() const`

Returns:

  `!` `owns_lock()`.

Throws:

  Nothing.

##### `Lockable* release()`

Effects:

  The association between `*this` and the `Lockable` object is removed, without affecting the lock state of the `Lockable` object. If `owns_lock()` would have returned `true`, it is the responsibility of the calling code to ensure that the `Lockable` is correctly unlocked.

Returns:

  A pointer to the `Lockable` object associated with `*this` at the point of the call, or `NULL` if there is no such object.

Throws:

  Nothing.

Postcondition:

  `*this` is no longer associated with any `Lockable` object. `mutex()` returns `NULL` and `owns_lock()` returns `false`.

#### Class template `upgrade_lock`

    template<typename Lockable>
    class upgrade_lock
    {
    public:
        explicit upgrade_lock(Lockable& m_);

        upgrade_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
        upgrade_lock(detail::thread_move_t<unique_lock<Lockable> > other);

        ~upgrade_lock();

        operator detail::thread_move_t<upgrade_lock<Lockable> >();
        detail::thread_move_t<upgrade_lock<Lockable> > move();

        upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
        upgrade_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);

        void swap(upgrade_lock& other);

        void lock();
        void unlock();

        operator unspecified-bool-type() const;
        bool operator!() const;
        bool owns_lock() const;
    };

Like `boost::unique_lock`, `boost::upgrade_lock` models the `Lockable` concept, but rather than acquiring unique ownership of the supplied `Lockable` object, locking an instance of `boost::upgrade_lock` acquires upgrade ownership.

Like `boost::unique_lock`, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the `lock()` member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a timeout. Consequently, `unlock()` is only called in the destructor if the lock object has locked the `Lockable` object, or otherwise adopted a lock on the `Lockable` object.

An instance of `boost::upgrade_lock` is said to own the lock state of a `Lockable` `m` if `mutex()` returns a pointer to `m` and `owns_lock()` returns `true`. If an object that owns the lock state of a `Lockable` object is destroyed, then the destructor will invoke `mutex()->unlock_upgrade()`.

The member functions of `boost::upgrade_lock` are not thread-safe. In particular, `boost::upgrade_lock` is intended to model the upgrade ownership of a `Lockable` object by a particular thread, and the member functions that release ownership of the lock state (including the destructor) must be called by the same thread that acquired ownership of the lock state.

#### Class template `upgrade_to_unique_lock`

    template <class Lockable>
    class upgrade_to_unique_lock
    {
    public:
        explicit upgrade_to_unique_lock(upgrade_lock<Lockable>& m_);

        ~upgrade_to_unique_lock();

        upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
        upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
        void swap(upgrade_to_unique_lock& other);

        operator unspecified-bool-type() const;
        bool operator!() const;
        bool owns_lock() const;
    };

`boost::upgrade_to_unique_lock` allows for a temporary upgrade of an `boost::upgrade_lock` to exclusive ownership. When constructed with a reference to an instance of `boost::upgrade_lock`, if that instance has upgrade ownership on some `Lockable` object, that ownership is upgraded to exclusive ownership. When the `boost::upgrade_to_unique_lock` instance is destroyed, the ownership of the `Lockable` is downgraded back to upgrade ownership.

### Mutex Types

#### Class `mutex`

    class mutex:
        boost::noncopyable
    {
    public:
        mutex();
        ~mutex();

        void lock();
        bool try_lock();
        void unlock();

        typedef unique_lock<mutex> scoped_lock;
        typedef scoped_lock scoped_try_lock;
    };

`boost::mutex` implements the `Lockable` concept to provide an exclusive-ownership mutex. At most one thread can own the lock on a given instance of `boost::mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()` and `unlock()` shall be permitted.

#### Typedef `try_mutex`

    typedef mutex try_mutex;

`boost::try_mutex` is a `typedef` to `boost::mutex`, provided for backwards compatibility with previous releases of boost.

#### Class `timed_mutex`

    class timed_mutex:
        boost::noncopyable
    {
    public:
        timed_mutex();
        ~timed_mutex();

        void lock();
        void unlock();
        bool try_lock();
        bool timed_lock(system_time const & abs_time);

        template<typename TimeDuration>
        bool timed_lock(TimeDuration const & relative_time);

        typedef unique_lock<timed_mutex> scoped_timed_lock;
        typedef scoped_timed_lock scoped_try_lock;
        typedef scoped_timed_lock scoped_lock;
    };

`boost::timed_mutex` implements the `TimedLockable` concept to provide an exclusive-ownership mutex. At most one thread can own the lock on a given instance of `boost::timed_mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()`, `timed_lock()`, `timed_lock()` and `unlock()` shall be permitted.

#### Class `recursive_mutex`

    class recursive_mutex:
        boost::noncopyable
    {
    public:
        recursive_mutex();
        ~recursive_mutex();

        void lock();
        bool try_lock();
        void unlock();

        typedef unique_lock<recursive_mutex> scoped_lock;
        typedef scoped_lock scoped_try_lock;
    };

`boost::recursive_mutex` implements the `Lockable` concept to provide an exclusive-ownership recursive mutex. At most one thread can own the lock on a given instance of `boost::recursive_mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()` and `unlock()` shall be permitted. A thread that already has exclusive ownership of a given `boost::recursive_mutex` instance can call `lock()` or `try_lock()` to acquire an additional level of ownership of the mutex. `unlock()` must be called once for each level of ownership acquired by a single thread before ownership can be acquired by another thread.

#### Typedef `recursive_try_mutex`

    typedef recursive_mutex recursive_try_mutex;

`boost::recursive_try_mutex` is a `typedef` to `boost::recursive_mutex`, provided for backwards compatibility with previous releases of boost.

#### Class `recursive_timed_mutex`

    class recursive_timed_mutex:
        boost::noncopyable
    {
    public:
        recursive_timed_mutex();
        ~recursive_timed_mutex();

        void lock();
        bool try_lock();
        void unlock();

        bool timed_lock(system_time const & abs_time);

        template<typename TimeDuration>
        bool timed_lock(TimeDuration const & relative_time);

        typedef unique_lock<recursive_timed_mutex> scoped_lock;
        typedef scoped_lock scoped_try_lock;
        typedef scoped_lock scoped_timed_lock;
    };

`boost::recursive_timed_mutex` implements the `TimedLockable` concept to provide an exclusive-ownership recursive mutex. At most one thread can own the lock on a given instance of `boost::recursive_timed_mutex` at any time. Multiple concurrent calls to `lock()`, `try_lock()`, `timed_lock()`, `timed_lock()` and `unlock()` shall be permitted. A thread that already has exclusive ownership of a given `boost::recursive_timed_mutex` instance can call `lock()`, `timed_lock()`, `timed_lock()` or `try_lock()` to acquire an additional level of ownership of the mutex. `unlock()` must be called once for each level of ownership acquired by a single thread before ownership can be acquired by another thread.

#### Class `shared_mutex`

    class shared_mutex
    {
    public:
        shared_mutex();
        ~shared_mutex();

        void lock_shared();
        bool try_lock_shared();
        bool timed_lock_shared(system_time const& timeout);
        void unlock_shared();

        void lock();
        bool try_lock();
        bool timed_lock(system_time const& timeout);
        void unlock();

        void lock_upgrade();
        void unlock_upgrade();

        void unlock_upgrade_and_lock();
        void unlock_and_lock_upgrade();
        void unlock_and_lock_shared();
        void unlock_upgrade_and_lock_shared();
    };

The class `boost::shared_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the `UpgradeLockable` concept.

Multiple concurrent calls to `lock()`, `try_lock()`, `timed_lock()`, `lock_shared()`, `try_lock_shared()` and `timed_lock_shared()` shall be permitted.

### Condition Variables

##### Synopsis

The classes `condition_variable` and `condition_variable_any` provide a mechanism for one thread to wait for notification from another thread that a particular condition has become true. The general usage pattern is that one thread locks a mutex and then calls `wait` on an instance of `condition_variable` or `condition_variable_any`. When the thread is woken from the wait, then it checks to see if the appropriate condition is now true, and continues if so. If the condition is not true, then the thread then calls `wait` again to resume waiting. In the simplest case, this condition is just a boolean variable:

    boost::condition_variable cond;
    boost::mutex mut;
    bool data_ready;

    void process_data();

    void wait_for_data_to_process()
    {
        boost::unique_lock<boost::mutex> lock(mut);
        while(!data_ready)
        {
            cond.wait(lock);
        }
        process_data();
    }

Notice that the `lock` is passed to `wait`: `wait` will atomically add the thread to the set of threads waiting on the condition variable, and unlock the mutex. When the thread is woken, the mutex will be locked again before the call to `wait` returns. This allows other threads to acquire the mutex in order to update the shared data, and ensures that the data associated with the condition is correctly synchronized.

In the mean time, another thread sets the condition to `true`, and then calls either `notify_one` or `notify_all` on the condition variable to wake one waiting thread or all the waiting threads respectively.

    void retrieve_data();
    void prepare_data();

    void prepare_data_for_processing()
    {
        retrieve_data();
        prepare_data();
        {
            boost::lock_guard<boost::mutex> lock(mut);
            data_ready=true;
        }
        cond.notify_one();
    }

Note that the same mutex is locked before the shared data is updated, but that the mutex does not have to be locked across the call to `notify_one`.

This example uses an object of type `condition_variable`, but would work just as well with an object of type `condition_variable_any`: `condition_variable_any` is more general, and will work with any kind of lock or mutex, whereas `condition_variable` requires that the lock passed to `wait` is an instance of `boost::unique_lock<boost::mutex>`. This enables `condition_variable` to make optimizations in some cases, based on the knowledge of the mutex type; `condition_variable_any` typically has a more complex implementation than `condition_variable`.

#### Class `condition_variable`

    namespace boost
    {
        class condition_variable
        {
        public:
            condition_variable();
            ~condition_variable();

            void wait(boost::unique_lock<boost::mutex>& lock);

            template<typename predicate_type>
            void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);

            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);

            template<typename duration_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);

            template<typename predicate_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);

            template<typename duration_type,typename predicate_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);

        // backwards compatibility

            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);

            template<typename predicate_type>
            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);
        };
    }

##### `condition_variable()`

Effects:

  Constructs an object of class `condition_variable`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `~condition_variable()`

Precondition:

  All threads waiting on `*this` have been notified by a call to `notify_one` or `notify_all` (though the respective calls to `wait` or `timed_wait` need not have returned).

Effects:

  Destroys the object.

Throws:

  Nothing.

##### `void notify_one()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks one of those threads.

Throws:

  Nothing.

##### `void notify_all()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks all of those threads.

Throws:

  Nothing.

##### `void wait(boost::unique_lock<boost::mutex>& lock)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `timed_wait` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename predicate_type> void wait(boost::unique_lock<boost::mutex>& lock, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          wait(lock);
      }

##### `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `timed_wait` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, when the time as reported by `boost::get_system_time()` would be equal to or later than the specified `abs_time`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time specified by `abs_time` was reached, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`

Precondition:

  `lock` is locked by the current thread, and either no other thread is currently waiting on `*this`, or the execution of the `mutex()` member function on the `lock` objects supplied in the calls to `wait` or `timed_wait` in all the threads currently waiting on `*this` would return the same value as `lock->mutex()` for this call to `wait`.

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, after the period of time indicated by the `rel_time` argument has elapsed, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time period specified by `rel_time` has elapsed, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

| Note
The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.

##### `template<typename predicate_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock, boost::system_time const& abs_time, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!timed_wait(lock,abs_time))
          {
              return pred();
          }
      }
      return true;

#### Class `condition_variable_any`

    namespace boost
    {
        class condition_variable_any
        {
        public:
            condition_variable_any();
            ~condition_variable_any();

            template<typename lock_type>
            void wait(lock_type& lock);

            template<typename lock_type,typename predicate_type>
            void wait(lock_type& lock,predicate_type predicate);

            template<typename lock_type>
            bool timed_wait(lock_type& lock,boost::system_time const& abs_time);

            template<typename lock_type,typename duration_type>
            bool timed_wait(lock_type& lock,duration_type const& rel_time);

            template<typename lock_type,typename predicate_type>
            bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate);

            template<typename lock_type,typename duration_type,typename predicate_type>
            bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate);

        // backwards compatibility

            template<typename lock_type>
            bool timed_wait(lock_type>& lock,boost::xtime const& abs_time);

            template<typename lock_type,typename predicate_type>
            bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate);
        };
    }

##### `condition_variable_any()`

Effects:

  Constructs an object of class `condition_variable_any`.

Throws:

  `boost::thread_resource_error` if an error occurs.

##### `~condition_variable_any()`

Precondition:

  All threads waiting on `*this` have been notified by a call to `notify_one` or `notify_all` (though the respective calls to `wait` or `timed_wait` need not have returned).

Effects:

  Destroys the object.

Throws:

  Nothing.

##### `void notify_one()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks one of those threads.

Throws:

  Nothing.

##### `void notify_all()`

Effects:

  If any threads are currently blocked waiting on `*this` in a call to `wait` or `timed_wait`, unblocks all of those threads.

Throws:

  Nothing.

##### `template<typename lock_type> void wait(lock_type& lock)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename lock_type,typename predicate_type> void wait(lock_type& lock, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          wait(lock);
      }

##### `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, when the time as reported by `boost::get_system_time()` would be equal to or later than the specified `abs_time`, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time specified by `abs_time` was reached, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

##### `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)`

Effects:

  Atomically call `lock.unlock()` and blocks the current thread. The thread will unblock when notified by a call to `this->notify_one()` or `this->notify_all()`, after the period of time indicated by the `rel_time` argument has elapsed, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking `lock.lock()` before the call to `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the function exits with an exception.

Returns:

  `false` if the call is returning because the time period specified by `rel_time` has elapsed, `true` otherwise.

Postcondition:

  `lock` is locked by the current thread.

Throws:

  `boost::thread_resource_error` if an error occurs. `boost::thread_interrupted` if the wait was interrupted by a call to `interrupt()` on the `boost::thread` object associated with the current thread of execution.

| Note
The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.

##### `template<typename lock_type,typename predicate_type> bool timed_wait(lock_type& lock, boost::system_time const& abs_time, predicate_type pred)`

Effects:

  As-if

      while(!pred())
      {
          if(!timed_wait(lock,abs_time))
          {
              return pred();
          }
      }
      return true;

#### Typedef `condition`

    typedef condition_variable_any condition;

The typedef `condition` is provided for backwards compatibility with previous boost releases.

### One-time Initialization

`boost::call_once` provides a mechanism for ensuring that an initialization routine is run exactly once without data races or deadlocks.

#### Typedef `once_flag`

    typedef platform-specific-type once_flag;
    #define BOOST_ONCE_INIT platform-specific-initializer

Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT`:

    boost::once_flag f=BOOST_ONCE_INIT;

#### Non-member function `call_once`

    template<typename Callable>
    void call_once(once_flag& flag,Callable func);

Requires:

  `Callable` is `CopyConstructible`. Copying `func` shall have no side effects, and the effect of calling the copy shall be equivalent to calling the original.

Effects:

  Calls to `call_once` on the same `once_flag` object are serialized. If there has been no prior effective `call_once` on the same `once_flag` object, the argument `func` (or a copy thereof) is called as-if by invoking `func(args)`, and the invocation of `call_once` is effective if and only if `func(args)` returns without exception. If an exception is thrown, the exception is propagated to the caller. If there has been a prior effective `call_once` on the same `once_flag` object, the `call_once` returns without invoking `func`.

Synchronization:

  The completion of an effective `call_once` invocation on a `once_flag` object, synchronizes with all subsequent `call_once` invocations on the same `once_flag` object.

Throws:

  `thread_resource_error` when the effects cannot be achieved. or any exception propagated from `func`.

    void call_once(void (*func)(),once_flag& flag);

This second overload is provided for backwards compatibility. The effects of `call_once(func,flag)` shall be the same as those of `call_once(flag,func)`.

### Barriers

A barrier is a simple concept. Also known as a rendezvous, it is a synchronization point between multiple threads. The barrier is configured for a particular number of threads (`n`), and as threads reach the barrier they must wait until all `n` threads have arrived. Once the `n`-th thread has reached the barrier, all the waiting threads can proceed, and the barrier is reset.

#### Class `barrier`

    #include <boost/thread/barrier.hpp>

    class barrier
    {
    public:
        barrier(unsigned int count);
        ~barrier();

        bool wait();
    };

Instances of `boost::barrier` are not copyable or movable.

###### Constructor

    barrier(unsigned int count);

Effects:

  Construct a barrier for `count` threads.

Throws:

  `boost::thread_resource_error` if an error occurs.

###### Destructor

    ~barrier();

Precondition:

  No threads are waiting on `*this`.

Effects:

  Destroys `*this`.

Throws:

  Nothing.

###### Member function `wait`

    bool wait();

Effects:

  Block until `count` threads have called `wait` on `*this`. When the `count`-th thread calls `wait`, all waiting threads are unblocked, and the barrier is reset.

Returns:

  `true` for exactly one thread from each batch of waiting threads, `false` otherwise.

Throws:

  `boost::thread_resource_error` if an error occurs.