2 (C) Copyright 2007-11 Anthony Williams.
3 (C) Copyright 2011-12 Vicente J. Botet Escriba.
4 Distributed under the Boost Software License, Version 1.0.
5 (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
9 [section:condvar_ref Condition Variables]
20 class condition_variable;
21 class condition_variable_any;
22 void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
25 The classes `condition_variable` and `condition_variable_any` provide a
26 mechanism for one thread to wait for notification from another thread that a
27 particular condition has become true. The general usage pattern is that one
28 thread locks a mutex and then calls `wait` on an instance of
29 `condition_variable` or `condition_variable_any`. When the thread is woken from
30 the wait, then it checks to see if the appropriate condition is now true, and
31 continues if so. If the condition is not true, then the thread then calls `wait`
32 again to resume waiting. In the simplest case, this condition is just a boolean
35 boost::condition_variable cond;
41 void wait_for_data_to_process()
43 boost::unique_lock<boost::mutex> lock(mut);
51 Notice that the `lock` is passed to `wait`: `wait` will atomically add the
52 thread to the set of threads waiting on the condition variable, and unlock the
53 mutex. When the thread is woken, the mutex will be locked again before the call
54 to `wait` returns. This allows other threads to acquire the mutex in order to
55 update the shared data, and ensures that the data associated with the condition
56 is correctly synchronized.
58 In the mean time, another thread sets the condition to `true`, and then calls
59 either `notify_one` or `notify_all` on the condition variable to wake one
60 waiting thread or all the waiting threads respectively.
65 void prepare_data_for_processing()
70 boost::lock_guard<boost::mutex> lock(mut);
76 Note that the same mutex is locked before the shared data is updated, but that
77 the mutex does not have to be locked across the call to `notify_one`.
79 This example uses an object of type `condition_variable`, but would work just as
80 well with an object of type `condition_variable_any`: `condition_variable_any`
81 is more general, and will work with any kind of lock or mutex, whereas
82 `condition_variable` requires that the lock passed to `wait` is an instance of
83 `boost::unique_lock<boost::mutex>`. This enables `condition_variable` to make
84 optimizations in some cases, based on the knowledge of the mutex type;
85 `condition_variable_any` typically has a more complex implementation than
88 [section:condition_variable Class `condition_variable`]
90 //#include <boost/thread/condition_variable.hpp>
94 class condition_variable
98 ~condition_variable();
100 void notify_one() noexcept;
101 void notify_all() noexcept;
103 void wait(boost::unique_lock<boost::mutex>& lock);
105 template<typename predicate_type>
106 void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);
108 template <class Clock, class Duration>
109 typename cv_status::type
111 unique_lock<mutex>& lock,
112 const chrono::time_point<Clock, Duration>& t);
114 template <class Clock, class Duration, class Predicate>
117 unique_lock<mutex>& lock,
118 const chrono::time_point<Clock, Duration>& t,
121 template <class Rep, class Period>
122 typename cv_status::type
124 unique_lock<mutex>& lock,
125 const chrono::duration<Rep, Period>& d);
127 template <class Rep, class Period, class Predicate>
130 unique_lock<mutex>& lock,
131 const chrono::duration<Rep, Period>& d,
134 #if defined BOOST_THREAD_USES_DATETIME
135 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);
136 template<typename duration_type>
137 bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);
138 template<typename predicate_type>
139 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);
140 template<typename duration_type,typename predicate_type>
141 bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);
142 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);
144 template<typename predicate_type>
145 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);
151 [section:constructor `condition_variable()`]
155 [[Effects:] [Constructs an object of class `condition_variable`.]]
157 [[Throws:] [__thread_resource_error__ if an error occurs.]]
163 [section:destructor `~condition_variable()`]
167 [[Precondition:] [All threads waiting on `*this` have been notified by a call to
168 `notify_one` or `notify_all` (though the respective calls to `wait` or
169 `timed_wait` need not have returned).]]
171 [[Effects:] [Destroys the object.]]
173 [[Throws:] [Nothing.]]
179 [section:notify_one `void notify_one()`]
183 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
184 to `wait` or `timed_wait`, unblocks one of those threads.]]
186 [[Throws:] [Nothing.]]
192 [section:notify_all `void notify_all()`]
196 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
197 to `wait` or `timed_wait`, unblocks all of those threads.]]
199 [[Throws:] [Nothing.]]
205 [section:wait `void wait(boost::unique_lock<boost::mutex>& lock)`]
209 [[Precondition:] [`lock` is locked by the current thread, and either no other
210 thread is currently waiting on `*this`, or the execution of the `mutex()` member
211 function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
212 in all the threads currently waiting on `*this` would return the same value as
213 `lock->mutex()` for this call to `wait`.]]
215 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
216 thread will unblock when notified by a call to `this->notify_one()` or
217 `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever
218 reason), the lock is reacquired by invoking `lock.lock()` before the call to
219 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
220 function exits with an exception.]]
222 [[Postcondition:] [`lock` is locked by the current thread.]]
224 [[Throws:] [__thread_resource_error__ if an error
225 occurs. __thread_interrupted__ if the wait was interrupted by a call to
226 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
232 [section:wait_predicate `template<typename predicate_type> void wait(boost::unique_lock<boost::mutex>& lock, predicate_type pred)`]
236 [[Effects:] [As-if ``
247 [section:timed_wait `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`]
251 [[Precondition:] [`lock` is locked by the current thread, and either no other
252 thread is currently waiting on `*this`, or the execution of the `mutex()` member
253 function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
254 in all the threads currently waiting on `*this` would return the same value as
255 `lock->mutex()` for this call to `wait`.]]
257 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
258 thread will unblock when notified by a call to `this->notify_one()` or
259 `this->notify_all()`, when the time as reported by `boost::get_system_time()`
260 would be equal to or later than the specified `abs_time`, or spuriously. When
261 the thread is unblocked (for whatever reason), the lock is reacquired by
262 invoking `lock.lock()` before the call to `wait` returns. The lock is also
263 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
265 [[Returns:] [`false` if the call is returning because the time specified by
266 `abs_time` was reached, `true` otherwise.]]
268 [[Postcondition:] [`lock` is locked by the current thread.]]
270 [[Throws:] [__thread_resource_error__ if an error
271 occurs. __thread_interrupted__ if the wait was interrupted by a call to
272 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
278 [section:timed_wait_rel `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`]
282 [[Precondition:] [`lock` is locked by the current thread, and either no other
283 thread is currently waiting on `*this`, or the execution of the `mutex()` member
284 function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
285 in all the threads currently waiting on `*this` would return the same value as
286 `lock->mutex()` for this call to `wait`.]]
288 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
289 thread will unblock when notified by a call to `this->notify_one()` or
290 `this->notify_all()`, after the period of time indicated by the `rel_time`
291 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
292 reason), the lock is reacquired by invoking `lock.lock()` before the call to
293 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
294 function exits with an exception.]]
296 [[Returns:] [`false` if the call is returning because the time period specified
297 by `rel_time` has elapsed, `true` otherwise.]]
299 [[Postcondition:] [`lock` is locked by the current thread.]]
301 [[Throws:] [__thread_resource_error__ if an error
302 occurs. __thread_interrupted__ if the wait was interrupted by a call to
303 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
307 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
311 [section:timed_wait_predicate `template<typename predicate_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock, boost::system_time const& abs_time, predicate_type pred)`]
315 [[Effects:] [As-if ``
318 if(!timed_wait(lock,abs_time))
331 [section:wait_until `template <class Clock, class Duration> cv_status wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time)`]
335 [[Precondition:] [`lock` is locked by the current thread, and either no other
336 thread is currently waiting on `*this`, or the execution of the `mutex()` member
337 function on the `lock` objects supplied in the calls to `wait` or `wait_for` or `wait_until`
338 in all the threads currently waiting on `*this` would return the same value as
339 `lock->mutex()` for this call to `wait`.]]
341 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
342 thread will unblock when notified by a call to `this->notify_one()` or
343 `this->notify_all()`, when the time as reported by `Clock::now()`
344 would be equal to or later than the specified `abs_time`, or spuriously. When
345 the thread is unblocked (for whatever reason), the lock is reacquired by
346 invoking `lock.lock()` before the call to `wait` returns. The lock is also
347 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
349 [[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
350 `abs_time` was reached, `cv_status::no_timeout` otherwise.]]
352 [[Postcondition:] [`lock` is locked by the current thread.]]
354 [[Throws:] [__thread_resource_error__ if an error
355 occurs. __thread_interrupted__ if the wait was interrupted by a call to
356 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
362 [section:wait_for `template <class Rep, class Period> cv_status wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time)`]
367 [[Precondition:] [`lock` is locked by the current thread, and either no other
368 thread is currently waiting on `*this`, or the execution of the `mutex()` member
369 function on the `lock` objects supplied in the calls to `wait` or `wait_until` or `wait_for`
370 in all the threads currently waiting on `*this` would return the same value as
371 `lock->mutex()` for this call to `wait`.]]
373 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
374 thread will unblock when notified by a call to `this->notify_one()` or
375 `this->notify_all()`, after the period of time indicated by the `rel_time`
376 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
377 reason), the lock is reacquired by invoking `lock.lock()` before the call to
378 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
379 function exits with an exception.]]
381 [[Returns:] [`cv_status::timeout ` if the call is returning because the time period specified
382 by `rel_time` has elapsed, `cv_status::no_timeout ` otherwise.]]
384 [[Postcondition:] [`lock` is locked by the current thread.]]
386 [[Throws:] [__thread_resource_error__ if an error
387 occurs. __thread_interrupted__ if the wait was interrupted by a call to
388 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
392 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
396 [section:wait_until_predicate `template <class Clock, class Duration, class Predicate> bool wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`]
401 [[Effects:] [As-if ``
404 if(!wait_until(lock,abs_time))
416 [section:wait_for_predicate `template <class Rep, class Period, class Predicate> bool wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`]
421 [[Effects:] [As-if ``
422 return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
434 [section:condition_variable_any Class `condition_variable_any`]
436 //#include <boost/thread/condition_variable.hpp>
440 class condition_variable_any
443 condition_variable_any();
444 ~condition_variable_any();
449 template<typename lock_type>
450 void wait(lock_type& lock);
452 template<typename lock_type,typename predicate_type>
453 void wait(lock_type& lock,predicate_type predicate);
455 template <class lock_type, class Clock, class Duration>
456 cv_status wait_until(
458 const chrono::time_point<Clock, Duration>& t);
460 template <class lock_type, class Clock, class Duration, class Predicate>
463 const chrono::time_point<Clock, Duration>& t,
467 template <class lock_type, class Rep, class Period>
470 const chrono::duration<Rep, Period>& d);
472 template <class lock_type, class Rep, class Period, class Predicate>
475 const chrono::duration<Rep, Period>& d,
478 #if defined BOOST_THREAD_USES_DATETIME
479 template<typename lock_type>
480 bool timed_wait(lock_type& lock,boost::system_time const& abs_time);
481 template<typename lock_type,typename duration_type>
482 bool timed_wait(lock_type& lock,duration_type const& rel_time);
483 template<typename lock_type,typename predicate_type>
484 bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate);
485 template<typename lock_type,typename duration_type,typename predicate_type>
486 bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate);
487 template<typename lock_type>
488 bool timed_wait(lock_type>& lock,boost::xtime const& abs_time);
489 template<typename lock_type,typename predicate_type>
490 bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate);
495 [section:constructor `condition_variable_any()`]
499 [[Effects:] [Constructs an object of class `condition_variable_any`.]]
501 [[Throws:] [__thread_resource_error__ if an error occurs.]]
507 [section:destructor `~condition_variable_any()`]
511 [[Precondition:] [All threads waiting on `*this` have been notified by a call to
512 `notify_one` or `notify_all` (though the respective calls to `wait` or
513 `timed_wait` need not have returned).]]
515 [[Effects:] [Destroys the object.]]
517 [[Throws:] [Nothing.]]
523 [section:notify_one `void notify_one()`]
527 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
528 to `wait` or `timed_wait`, unblocks one of those threads.]]
530 [[Throws:] [Nothing.]]
536 [section:notify_all `void notify_all()`]
540 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
541 to `wait` or `timed_wait`, unblocks all of those threads.]]
543 [[Throws:] [Nothing.]]
549 [section:wait `template<typename lock_type> void wait(lock_type& lock)`]
553 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
554 thread will unblock when notified by a call to `this->notify_one()` or
555 `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever
556 reason), the lock is reacquired by invoking `lock.lock()` before the call to
557 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
558 function exits with an exception.]]
560 [[Postcondition:] [`lock` is locked by the current thread.]]
562 [[Throws:] [__thread_resource_error__ if an error
563 occurs. __thread_interrupted__ if the wait was interrupted by a call to
564 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
570 [section:wait_predicate `template<typename lock_type,typename predicate_type> void wait(lock_type& lock, predicate_type pred)`]
574 [[Effects:] [As-if ``
585 [section:timed_wait `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)`]
589 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
590 thread will unblock when notified by a call to `this->notify_one()` or
591 `this->notify_all()`, when the time as reported by `boost::get_system_time()`
592 would be equal to or later than the specified `abs_time`, or spuriously. When
593 the thread is unblocked (for whatever reason), the lock is reacquired by
594 invoking `lock.lock()` before the call to `wait` returns. The lock is also
595 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
597 [[Returns:] [`false` if the call is returning because the time specified by
598 `abs_time` was reached, `true` otherwise.]]
600 [[Postcondition:] [`lock` is locked by the current thread.]]
602 [[Throws:] [__thread_resource_error__ if an error
603 occurs. __thread_interrupted__ if the wait was interrupted by a call to
604 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
610 [section:timed_wait_rel `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)`]
614 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
615 thread will unblock when notified by a call to `this->notify_one()` or
616 `this->notify_all()`, after the period of time indicated by the `rel_time`
617 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
618 reason), the lock is reacquired by invoking `lock.lock()` before the call to
619 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
620 function exits with an exception.]]
622 [[Returns:] [`false` if the call is returning because the time period specified
623 by `rel_time` has elapsed, `true` otherwise.]]
625 [[Postcondition:] [`lock` is locked by the current thread.]]
627 [[Throws:] [__thread_resource_error__ if an error
628 occurs. __thread_interrupted__ if the wait was interrupted by a call to
629 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
633 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
637 [section:timed_wait_predicate `template<typename lock_type,typename predicate_type> bool timed_wait(lock_type& lock, boost::system_time const& abs_time, predicate_type pred)`]
641 [[Effects:] [As-if ``
644 if(!timed_wait(lock,abs_time))
656 [section:wait_until `template <class lock_type, class Clock, class Duration> cv_status wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time)`]
660 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
661 thread will unblock when notified by a call to `this->notify_one()` or
662 `this->notify_all()`, when the time as reported by `Clock::now()`
663 would be equal to or later than the specified `abs_time`, or spuriously. When
664 the thread is unblocked (for whatever reason), the lock is reacquired by
665 invoking `lock.lock()` before the call to `wait` returns. The lock is also
666 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
668 [[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
669 `abs_time` was reached, `cv_status::no_timeout` otherwise.]]
671 [[Postcondition:] [`lock` is locked by the current thread.]]
673 [[Throws:] [__thread_resource_error__ if an error
674 occurs. __thread_interrupted__ if the wait was interrupted by a call to
675 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
681 [section:wait_for `template <class lock_type, class Rep, class Period> cv_status wait_for(lock_type& lock, const chrono::duration<Rep, Period>& rel_time)`]
685 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
686 thread will unblock when notified by a call to `this->notify_one()` or
687 `this->notify_all()`, after the period of time indicated by the `rel_time`
688 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
689 reason), the lock is reacquired by invoking `lock.lock()` before the call to
690 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
691 function exits with an exception.]]
693 [[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
694 `abs_time` was reached, `cv_status::no_timeout` otherwise.]]
696 [[Postcondition:] [`lock` is locked by the current thread.]]
698 [[Throws:] [__thread_resource_error__ if an error
699 occurs. __thread_interrupted__ if the wait was interrupted by a call to
700 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
704 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
708 [section:wait_until_predicate `template <class lock_type, class Clock, class Duration, class Predicate> bool wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`]
712 [[Effects:] [As-if ``
715 if(!__cvany_wait_until(lock,abs_time))
727 [section:wait_for_predicate `template <class lock_type, class Rep, class Period, class Predicate> bool wait_for(lock_type& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`]
731 [[Effects:] [As-if ``
732 return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
741 [section:condition Typedef `condition` DEPRECATED V3]
743 // #include <boost/thread/condition.hpp>
747 typedef condition_variable_any condition;
751 The typedef `condition` is provided for backwards compatibility with previous boost releases.
756 [section:notify_all_at_thread_exit Non-member Function `notify_all_at_thread_exit`()]
758 // #include <boost/thread/condition_variable.hpp>
762 void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
767 [[Requires:] [`lk` is locked by the calling thread and either no other thread is waiting on `cond`, or `lk.mutex()` returns the same value for each of the lock arguments supplied by all concurrently waiting (via `wait`, `wait_for`, or `wait_until`) threads.]]
768 [[Effects:] [transfers ownership of the lock associated with `lk` into internal storage and schedules `cond` to be notified when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed. This notification shall be as if
780 [[Synchronization:] [The call to notify_all_at_thread_exit and the completion of the destructors for all the current threadÕs variables of thread storage duration synchronize with (1.10) calls to functions waiting on cond.
782 [[Note:] [The supplied lock will be held until the thread exits, and care must be taken to ensure that this does not cause deadlock due to lock ordering issues. After calling notify_all_at_thread_exit it is recommended that the thread should be exited as soon as possible, and that no blocking or time-consuming tasks are run on that thread.
784 [[Note:] [It is the userÕs responsibility to ensure that waiting threads do not erroneously assume that the thread has finished if they experience spurious wakeups. This typically requires that the condition being waited for is satisfied while holding the lock on lk, and that this lock is not released and reacquired prior to calling notify_all_at_thread_exit.