Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Latches -- EXPERIMENTAL

Introdcution
Examples
Class latch
Constructor latch(std::size_t)
Destructor ~latch()
Member Function wait()
Member Function try_wait()
Member Function wait_for()
Member Function wait_until()
Member Function count_down()
Member Function count_down_and_wait()
Member Function reset()

Latches are a thread co-ordination mechanism that allow one or more threads to block until one or more threads have reached a point.

Sample use cases for the latch include:

  • Setting multiple threads to perform a task, and then waiting until all threads have reached a common point.
  • Creating multiple threads, which wait for a signal before advancing beyond a common point.

An example of the first use case would be as follows:

void DoWork(thread_pool* pool) {
  latch completion_latch(NTASKS);
  for (int i = 0; i < NTASKS; ++i) {
    pool->submit([&] {
      // perform work
      ...
      completion_latch.count_down();
    }));
  }
  // Block until work is done
  completion_latch.wait();
}

An example of the second use case is shown below. We need to load data and then process it using a number of threads. Loading the data is I/O bound, whereas starting threads and creating data structures is CPU bound. By running these in parallel, throughput can be increased.

void DoWork() {
  latch start_latch(1);
  vector<thread*> workers;
  for (int i = 0; i < NTHREADS; ++i) {
    workers.push_back(new thread([&] {
      // Initialize data structures. This is CPU bound.
      ...
      start_latch.wait();
      // perform work
      ...
    }));
  }
  // Load input data. This is I/O bound.
  ...
  // Threads can now start processing
  start_latch.count_down();
  }
#include <boost/thread/latch.hpp>

class latch
{
public:
    latch(latch const&) = delete;
    latch& operator=(latch const&) = delete;

    latch(std::size_t count);
    ~latch();

    void wait();
    bool try_wait();
    template <class Rep, class Period>
    cv_status wait_for(const chrono::duration<Rep, Period>& rel_time);
    template <class lock_type, class Clock, class Duration>
    cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time);
    void count_down();
    void count_down_and_wait();

};

A latch maintains an internal counter that is initialized when the latch is created. One or more threads may block waiting until the counter is decremented to 0.

Instances of latch are not copyable or movable.

latch(std::size_t count);

Effects:

Construct a latch with is initial value for the internal counter.

Note:

The counter could be zero.

Throws:

Nothing.

~latch();

Precondition:

No threads are waiting or invoking count_down on *this.

Effects:

Destroys *this latch.

Throws:

Nothing.

void wait();

Effects:

Block the calling thread until the internal count reaches the value zero. Then all waiting threads are unblocked.

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.

Notes:

wait() is an interruption point.

bool try_wait();

Returns:

Returns true if the internal count is 0, and false otherwise. Does not block the calling thread.

Throws:

- boost::thread_resource_error if an error occurs.

template <class Rep, class Period>
cv_status wait_for(const chrono::duration<Rep, Period>& rel_time);

Effects:

Block the calling thread until the internal count reaches the value zero or the duration has been elapsed. If no timeout, all waiting threads are unblocked.

Returns:

cv_status::no_timeout if the internal count is 0, and cv_status::timeout if duration has been elapsed.

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.

Notes:

wait_for() is an interruption point.

template <class lock_type, class Clock, class Duration>
cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time);

Effects:

Block the calling thread until the internal count reaches the value zero or the time_point has been reached. If no timeout, all waiting threads are unblocked.

Returns:

cv_status::no_timeout if the internal count is 0, and cv_status::timeout if time_point has been reached.

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.

Notes:

wait_until() is an interruption point.

void count_down();

Requires:

The internal counter is non zero.

Effects:

Decrements the internal count by 1, and returns. If the count reaches 0, any threads blocked in wait() will be released.

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.

Notes:

count_down() is an interruption point.

void count_down_and_wait();

Requires:

The internal counter is non zero.

Effects:

Decrements the internal count by 1. If the resulting count is not 0, blocks the calling thread until the internal count is decremented to 0 by one or more other threads calling count_down() or count_down_and_wait().

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.

Notes:

count_down_and_wait() is an interruption point.

[

reset( size_t );

Requires:

This function may only be invoked when there are no other threads currently inside the waiting functions.

Returns:

Resets the latch with a new value for the initial thread count.

Throws:

- boost::thread_resource_error if an error occurs.

]


PrevUpHomeNext