]>
Commit | Line | Data |
---|---|---|
1 | [/ | |
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). | |
7 | ] | |
8 | ||
9 | [section:condvar_ref Condition Variables] | |
10 | ||
11 | [heading Synopsis] | |
12 | ||
13 | namespace boost | |
14 | { | |
15 | enum class cv_status; | |
16 | { | |
17 | no_timeout, | |
18 | timeout | |
19 | }; | |
20 | class condition_variable; | |
21 | class condition_variable_any; | |
22 | void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); | |
23 | } | |
24 | ||
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 | |
33 | variable: | |
34 | ||
35 | boost::condition_variable cond; | |
36 | boost::mutex mut; | |
37 | bool data_ready; | |
38 | ||
39 | void process_data(); | |
40 | ||
41 | void wait_for_data_to_process() | |
42 | { | |
43 | boost::unique_lock<boost::mutex> lock(mut); | |
44 | while(!data_ready) | |
45 | { | |
46 | cond.wait(lock); | |
47 | } | |
48 | process_data(); | |
49 | } | |
50 | ||
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. | |
57 | ||
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. | |
61 | ||
62 | void retrieve_data(); | |
63 | void prepare_data(); | |
64 | ||
65 | void prepare_data_for_processing() | |
66 | { | |
67 | retrieve_data(); | |
68 | prepare_data(); | |
69 | { | |
70 | boost::lock_guard<boost::mutex> lock(mut); | |
71 | data_ready=true; | |
72 | } | |
73 | cond.notify_one(); | |
74 | } | |
75 | ||
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`. | |
78 | ||
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 | |
86 | `condition_variable`. | |
87 | ||
88 | [section:condition_variable Class `condition_variable`] | |
89 | ||
90 | //#include <boost/thread/condition_variable.hpp> | |
91 | ||
92 | namespace boost | |
93 | { | |
94 | class condition_variable | |
95 | { | |
96 | public: | |
97 | condition_variable(); | |
98 | ~condition_variable(); | |
99 | ||
100 | void notify_one() noexcept; | |
101 | void notify_all() noexcept; | |
102 | ||
103 | void wait(boost::unique_lock<boost::mutex>& lock); | |
104 | ||
105 | template<typename predicate_type> | |
106 | void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate); | |
107 | ||
108 | template <class Clock, class Duration> | |
109 | typename cv_status::type | |
110 | wait_until( | |
111 | unique_lock<mutex>& lock, | |
112 | const chrono::time_point<Clock, Duration>& t); | |
113 | ||
114 | template <class Clock, class Duration, class Predicate> | |
115 | bool | |
116 | wait_until( | |
117 | unique_lock<mutex>& lock, | |
118 | const chrono::time_point<Clock, Duration>& t, | |
119 | Predicate pred); | |
120 | ||
121 | template <class Rep, class Period> | |
122 | typename cv_status::type | |
123 | wait_for( | |
124 | unique_lock<mutex>& lock, | |
125 | const chrono::duration<Rep, Period>& d); | |
126 | ||
127 | template <class Rep, class Period, class Predicate> | |
128 | bool | |
129 | wait_for( | |
130 | unique_lock<mutex>& lock, | |
131 | const chrono::duration<Rep, Period>& d, | |
132 | Predicate pred); | |
133 | ||
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); | |
143 | ||
144 | template<typename predicate_type> | |
145 | bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate); | |
146 | #endif | |
147 | ||
148 | }; | |
149 | } | |
150 | ||
151 | [section:constructor `condition_variable()`] | |
152 | ||
153 | [variablelist | |
154 | ||
155 | [[Effects:] [Constructs an object of class `condition_variable`.]] | |
156 | ||
157 | [[Throws:] [__thread_resource_error__ if an error occurs.]] | |
158 | ||
159 | ] | |
160 | ||
161 | [endsect] | |
162 | ||
163 | [section:destructor `~condition_variable()`] | |
164 | ||
165 | [variablelist | |
166 | ||
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).]] | |
170 | ||
171 | [[Effects:] [Destroys the object.]] | |
172 | ||
173 | [[Throws:] [Nothing.]] | |
174 | ||
175 | ] | |
176 | ||
177 | [endsect] | |
178 | ||
179 | [section:notify_one `void notify_one()`] | |
180 | ||
181 | [variablelist | |
182 | ||
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.]] | |
185 | ||
186 | [[Throws:] [Nothing.]] | |
187 | ||
188 | ] | |
189 | ||
190 | [endsect] | |
191 | ||
192 | [section:notify_all `void notify_all()`] | |
193 | ||
194 | [variablelist | |
195 | ||
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.]] | |
198 | ||
199 | [[Throws:] [Nothing.]] | |
200 | ||
201 | ] | |
202 | ||
203 | [endsect] | |
204 | ||
205 | [section:wait `void wait(boost::unique_lock<boost::mutex>& lock)`] | |
206 | ||
207 | [variablelist | |
208 | ||
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`.]] | |
214 | ||
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.]] | |
221 | ||
222 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
223 | ||
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.]] | |
227 | ||
228 | ] | |
229 | ||
230 | [endsect] | |
231 | ||
232 | [section:wait_predicate `template<typename predicate_type> void wait(boost::unique_lock<boost::mutex>& lock, predicate_type pred)`] | |
233 | ||
234 | [variablelist | |
235 | ||
236 | [[Effects:] [As-if `` | |
237 | while(!pred()) | |
238 | { | |
239 | wait(lock); | |
240 | } | |
241 | ``]] | |
242 | ||
243 | ] | |
244 | ||
245 | [endsect] | |
246 | ||
247 | [section:timed_wait `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`] | |
248 | ||
249 | [variablelist | |
250 | ||
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`.]] | |
256 | ||
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.]] | |
264 | ||
265 | [[Returns:] [`false` if the call is returning because the time specified by | |
266 | `abs_time` was reached, `true` otherwise.]] | |
267 | ||
268 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
269 | ||
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.]] | |
273 | ||
274 | ] | |
275 | ||
276 | [endsect] | |
277 | ||
278 | [section:timed_wait_rel `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`] | |
279 | ||
280 | [variablelist | |
281 | ||
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`.]] | |
287 | ||
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.]] | |
295 | ||
296 | [[Returns:] [`false` if the call is returning because the time period specified | |
297 | by `rel_time` has elapsed, `true` otherwise.]] | |
298 | ||
299 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
300 | ||
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.]] | |
304 | ||
305 | ] | |
306 | ||
307 | [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.] | |
308 | ||
309 | [endsect] | |
310 | ||
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)`] | |
312 | ||
313 | [variablelist | |
314 | ||
315 | [[Effects:] [As-if `` | |
316 | while(!pred()) | |
317 | { | |
318 | if(!timed_wait(lock,abs_time)) | |
319 | { | |
320 | return pred(); | |
321 | } | |
322 | } | |
323 | return true; | |
324 | ``]] | |
325 | ||
326 | ] | |
327 | ||
328 | [endsect] | |
329 | ||
330 | ||
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)`] | |
332 | ||
333 | [variablelist | |
334 | ||
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`.]] | |
340 | ||
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.]] | |
348 | ||
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.]] | |
351 | ||
352 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
353 | ||
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.]] | |
357 | ||
358 | ] | |
359 | ||
360 | [endsect] | |
361 | ||
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)`] | |
363 | ||
364 | ||
365 | [variablelist | |
366 | ||
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`.]] | |
372 | ||
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.]] | |
380 | ||
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.]] | |
383 | ||
384 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
385 | ||
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.]] | |
389 | ||
390 | ] | |
391 | ||
392 | [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.] | |
393 | ||
394 | [endsect] | |
395 | ||
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)`] | |
397 | ||
398 | ||
399 | [variablelist | |
400 | ||
401 | [[Effects:] [As-if `` | |
402 | while(!pred()) | |
403 | { | |
404 | if(!wait_until(lock,abs_time)) | |
405 | { | |
406 | return pred(); | |
407 | } | |
408 | } | |
409 | return true; | |
410 | ``]] | |
411 | ||
412 | ] | |
413 | ||
414 | [endsect] | |
415 | ||
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)`] | |
417 | ||
418 | ||
419 | [variablelist | |
420 | ||
421 | [[Effects:] [As-if `` | |
422 | return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred)); | |
423 | ``]] | |
424 | ||
425 | ] | |
426 | ||
427 | [endsect] | |
428 | ||
429 | ||
430 | ||
431 | ||
432 | [endsect] | |
433 | ||
434 | [section:condition_variable_any Class `condition_variable_any`] | |
435 | ||
436 | //#include <boost/thread/condition_variable.hpp> | |
437 | ||
438 | namespace boost | |
439 | { | |
440 | class condition_variable_any | |
441 | { | |
442 | public: | |
443 | condition_variable_any(); | |
444 | ~condition_variable_any(); | |
445 | ||
446 | void notify_one(); | |
447 | void notify_all(); | |
448 | ||
449 | template<typename lock_type> | |
450 | void wait(lock_type& lock); | |
451 | ||
452 | template<typename lock_type,typename predicate_type> | |
453 | void wait(lock_type& lock,predicate_type predicate); | |
454 | ||
455 | template <class lock_type, class Clock, class Duration> | |
456 | cv_status wait_until( | |
457 | lock_type& lock, | |
458 | const chrono::time_point<Clock, Duration>& t); | |
459 | ||
460 | template <class lock_type, class Clock, class Duration, class Predicate> | |
461 | bool wait_until( | |
462 | lock_type& lock, | |
463 | const chrono::time_point<Clock, Duration>& t, | |
464 | Predicate pred); | |
465 | ||
466 | ||
467 | template <class lock_type, class Rep, class Period> | |
468 | cv_status wait_for( | |
469 | lock_type& lock, | |
470 | const chrono::duration<Rep, Period>& d); | |
471 | ||
472 | template <class lock_type, class Rep, class Period, class Predicate> | |
473 | bool wait_for( | |
474 | lock_type& lock, | |
475 | const chrono::duration<Rep, Period>& d, | |
476 | Predicate pred); | |
477 | ||
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); | |
491 | #endif | |
492 | }; | |
493 | } | |
494 | ||
495 | [section:constructor `condition_variable_any()`] | |
496 | ||
497 | [variablelist | |
498 | ||
499 | [[Effects:] [Constructs an object of class `condition_variable_any`.]] | |
500 | ||
501 | [[Throws:] [__thread_resource_error__ if an error occurs.]] | |
502 | ||
503 | ] | |
504 | ||
505 | [endsect] | |
506 | ||
507 | [section:destructor `~condition_variable_any()`] | |
508 | ||
509 | [variablelist | |
510 | ||
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).]] | |
514 | ||
515 | [[Effects:] [Destroys the object.]] | |
516 | ||
517 | [[Throws:] [Nothing.]] | |
518 | ||
519 | ] | |
520 | ||
521 | [endsect] | |
522 | ||
523 | [section:notify_one `void notify_one()`] | |
524 | ||
525 | [variablelist | |
526 | ||
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.]] | |
529 | ||
530 | [[Throws:] [Nothing.]] | |
531 | ||
532 | ] | |
533 | ||
534 | [endsect] | |
535 | ||
536 | [section:notify_all `void notify_all()`] | |
537 | ||
538 | [variablelist | |
539 | ||
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.]] | |
542 | ||
543 | [[Throws:] [Nothing.]] | |
544 | ||
545 | ] | |
546 | ||
547 | [endsect] | |
548 | ||
549 | [section:wait `template<typename lock_type> void wait(lock_type& lock)`] | |
550 | ||
551 | [variablelist | |
552 | ||
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.]] | |
559 | ||
560 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
561 | ||
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.]] | |
565 | ||
566 | ] | |
567 | ||
568 | [endsect] | |
569 | ||
570 | [section:wait_predicate `template<typename lock_type,typename predicate_type> void wait(lock_type& lock, predicate_type pred)`] | |
571 | ||
572 | [variablelist | |
573 | ||
574 | [[Effects:] [As-if `` | |
575 | while(!pred()) | |
576 | { | |
577 | wait(lock); | |
578 | } | |
579 | ``]] | |
580 | ||
581 | ] | |
582 | ||
583 | [endsect] | |
584 | ||
585 | [section:timed_wait `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)`] | |
586 | ||
587 | [variablelist | |
588 | ||
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.]] | |
596 | ||
597 | [[Returns:] [`false` if the call is returning because the time specified by | |
598 | `abs_time` was reached, `true` otherwise.]] | |
599 | ||
600 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
601 | ||
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.]] | |
605 | ||
606 | ] | |
607 | ||
608 | [endsect] | |
609 | ||
610 | [section:timed_wait_rel `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)`] | |
611 | ||
612 | [variablelist | |
613 | ||
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.]] | |
621 | ||
622 | [[Returns:] [`false` if the call is returning because the time period specified | |
623 | by `rel_time` has elapsed, `true` otherwise.]] | |
624 | ||
625 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
626 | ||
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.]] | |
630 | ||
631 | ] | |
632 | ||
633 | [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.] | |
634 | ||
635 | [endsect] | |
636 | ||
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)`] | |
638 | ||
639 | [variablelist | |
640 | ||
641 | [[Effects:] [As-if `` | |
642 | while(!pred()) | |
643 | { | |
644 | if(!timed_wait(lock,abs_time)) | |
645 | { | |
646 | return pred(); | |
647 | } | |
648 | } | |
649 | return true; | |
650 | ``]] | |
651 | ||
652 | ] | |
653 | ||
654 | [endsect] | |
655 | ||
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)`] | |
657 | ||
658 | [variablelist | |
659 | ||
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.]] | |
667 | ||
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.]] | |
670 | ||
671 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
672 | ||
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.]] | |
676 | ||
677 | ] | |
678 | ||
679 | [endsect] | |
680 | ||
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)`] | |
682 | ||
683 | [variablelist | |
684 | ||
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.]] | |
692 | ||
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.]] | |
695 | ||
696 | [[Postcondition:] [`lock` is locked by the current thread.]] | |
697 | ||
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.]] | |
701 | ||
702 | ] | |
703 | ||
704 | [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.] | |
705 | ||
706 | [endsect] | |
707 | ||
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)`] | |
709 | ||
710 | [variablelist | |
711 | ||
712 | [[Effects:] [As-if `` | |
713 | while(!pred()) | |
714 | { | |
715 | if(!__cvany_wait_until(lock,abs_time)) | |
716 | { | |
717 | return pred(); | |
718 | } | |
719 | } | |
720 | return true; | |
721 | ``]] | |
722 | ||
723 | ] | |
724 | ||
725 | [endsect] | |
726 | ||
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)`] | |
728 | ||
729 | [variablelist | |
730 | ||
731 | [[Effects:] [As-if `` | |
732 | return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred)); | |
733 | ``]] | |
734 | ||
735 | ] | |
736 | ||
737 | [endsect] | |
738 | ||
739 | [endsect] | |
740 | ||
741 | [section:condition Typedef `condition` DEPRECATED V3] | |
742 | ||
743 | // #include <boost/thread/condition.hpp> | |
744 | namespace boost | |
745 | { | |
746 | ||
747 | typedef condition_variable_any condition; | |
748 | ||
749 | } | |
750 | ||
751 | The typedef `condition` is provided for backwards compatibility with previous boost releases. | |
752 | ||
753 | [endsect] | |
754 | ||
755 | ||
756 | [section:notify_all_at_thread_exit Non-member Function `notify_all_at_thread_exit`()] | |
757 | ||
758 | // #include <boost/thread/condition_variable.hpp> | |
759 | ||
760 | namespace boost | |
761 | { | |
762 | void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); | |
763 | } | |
764 | ||
765 | [variablelist | |
766 | ||
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 | |
769 | ||
770 | `` | |
771 | lk.unlock(); | |
772 | cond.notify_all(); | |
773 | `` | |
774 | ||
775 | ]] | |
776 | ||
777 | ] | |
778 | ||
779 | [/ | |
780 | Content-type: text/html ]>