Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / thread / doc / thread_ref.qbk
1 [/
2   (C) Copyright 2007-8 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:thread_management Thread Management]
10
11 [section:synopsis Synopsis]
12
13   #include <boost/thread/thread.hpp>
14
15   namespace boost 
16   {
17     class thread;
18     void swap(thread& lhs,thread& rhs) noexcept;
19
20     namespace this_thread 
21     {
22       thread::id get_id() noexcept;
23       template<typename TimeDuration>
24       void yield() noexcept; // DEPRECATED
25       template <class Clock, class Duration>
26       void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 
27       template <class Rep, class Period>
28       void sleep_for(const chrono::duration<Rep, Period>& rel_time);
29       namespace no_interruption_point  // EXTENSION
30       {
31         template <class Clock, class Duration>
32         void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 
33         template <class Rep, class Period>
34         void sleep_for(const chrono::duration<Rep, Period>& rel_time);
35       }
36       template<typename Callable>
37       void at_thread_exit(Callable func); // EXTENSION
38
39       void interruption_point(); // EXTENSION
40       bool interruption_requested() noexcept; // EXTENSION
41       bool interruption_enabled() noexcept; // EXTENSION 
42       class disable_interruption; // EXTENSION
43       class restore_interruption; // EXTENSION
44
45     #if defined BOOST_THREAD_USES_DATETIME
46       template <TimeDuration>
47       void sleep(TimeDuration const& rel_time);  // DEPRECATED
48       void sleep(system_time const& abs_time); // DEPRECATED
49     #endif
50     }
51     class thread_group; // EXTENSION
52
53   }
54
55 [endsect] [/section:synopsis Synopsis]
56
57 [section:tutorial Tutorial]
58
59 The __thread__ class is responsible for launching and managing threads. Each __thread__ object represents a single thread of execution,
60 or __not_a_thread__, and at most one __thread__ object represents a given thread of execution: objects of type __thread__ are not
61 copyable.
62
63 Objects of type __thread__ are movable, however, so they can be stored in move-aware containers, and returned from functions. This
64 allows the details of thread creation to be wrapped in a function.
65
66     boost::thread make_thread();
67
68     void f()
69     {
70         boost::thread some_thread=make_thread();
71         some_thread.join();
72     }
73
74 [note On compilers that support rvalue references, __thread__ provides a proper move constructor and move-assignment operator, and
75 therefore meets the C++0x ['MoveConstructible] and ['MoveAssignable] concepts. With such compilers, __thread__ can therefore be used
76 with containers that support those concepts.
77
78 For other compilers, move support is provided with a move emulation layer, so containers must explicitly detect that move emulation
79 layer. See <boost/thread/detail/move.hpp> for details.]
80
81 [section:launching Launching threads]
82
83 A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The
84 object is then copied into internal storage, and invoked on the newly-created thread of execution. If the object must not (or
85 cannot) be copied, then `boost::ref` can be used to pass in a reference to the function object. In this case, the user of
86 __boost_thread__ must ensure that the referred-to object outlives the newly-created thread of execution.
87
88     struct callable
89     {
90         void operator()();
91     };
92
93     boost::thread copies_are_safe()
94     {
95         callable x;
96         return boost::thread(x);
97     } // x is destroyed, but the newly-created thread has a copy, so this is OK
98
99     boost::thread oops()
100     {
101         callable x;
102         return boost::thread(boost::ref(x));
103     } // x is destroyed, but the newly-created thread still has a reference
104       // this leads to undefined behaviour
105
106 If you wish to construct an instance of __thread__ with a function or callable object that requires arguments to be supplied,
107 this can be done by passing additional arguments to the __thread__ constructor:
108
109     void find_the_question(int the_answer);
110
111     boost::thread deep_thought_2(find_the_question,42);
112
113 The arguments are ['copied] into the internal thread structure: if a reference is required, use `boost::ref`, just as for references
114 to callable functions.
115
116 There is an unspecified limit on the number of additional arguments that can be passed.
117
118 [endsect]
119
120 [section:attributes Thread attributes]
121
122 Thread launched in this way are created with implementation defined thread attributes as stack size, scheduling, 
123 priority, ... or any platform specific attributes. It is not evident how to provide a portable interface that allows 
124 the user to set the platform specific attributes. Boost.Thread stay in the middle road through the class 
125 thread::attributes which allows to set at least in a portable way the stack size as follows:
126
127   boost::thread::attributes attrs;
128   attrs.set_size(4096*10);
129   boost::thread deep_thought_2(attrs, find_the_question, 42);
130
131 Even for this simple attribute there could be portable issues as some platforms could require that the stack size 
132 should have a minimal size and/or be a multiple of a given page size. 
133 The library adapts the requested size to the platform constraints so that the user doesn't need to take care of it.
134
135 This is the single attribute that is provided in a portable way. In order to set any other thread attribute at 
136 construction time the user needs to use non portable code.
137
138 On PThread platforms the user will need to get the thread attributes handle and use it for whatever attribute.
139
140 Next follows how the user could set the stack size and the scheduling policy on PThread platforms.
141
142     boost::thread::attributes attrs;
143     // set portable attributes
144     // ...
145     attr.set_stack_size(4096*10);
146     #if defined(BOOST_THREAD_PLATFORM_WIN32)
147         // ... window version
148     #elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
149         // ... pthread version
150         pthread_attr_setschedpolicy(attr.get_native_handle(), SCHED_RR);
151     #else
152     #error "Boost threads unavailable on this platform"
153     #endif
154     boost::thread th(attrs, find_the_question, 42);
155         
156 On Windows platforms it is not so simple as there is no type that compiles the thread attributes. 
157 There is a linked to the creation of a thread on Windows that is emulated via the thread::attributes class. This is the LPSECURITY_ATTRIBUTES lpThreadAttributes.
158 Boost.Thread provides a non portable set_security function so that the user can provide it before the thread creation as follows
159   
160 [/Boost.Thread creates Windows threads that are suspended. Then it calls to the virtual function set_attributes and last it resumes the thread. 
161 The user needs to define a class that inherits from the class thread::attributes that defines a virtual function set_attributes to set any specific Windows thread attribute.
162
163
164     class MyWinTthreadAttributes : boost::thread::attributes
165     {
166     public:
167       void set_attributes(boost::thread::native_handle_type h)
168       {
169         // use any specific windows thread setting
170         
171       }
172     };
173     #if defined(BOOST_THREAD_PLATFORM_WIN32)
174     
175       MyWinTthreadAttributes attrs;
176       // set portable attributes
177       // ...
178       attr.set_stack_size(4096*10);
179       boost::thread th(attrs, find_the_question, 42);
180     #else
181     #error "Platform not supported"
182     #endif
183
184 ]
185
186     #if defined(BOOST_THREAD_PLATFORM_WIN32)
187       boost::thread::attributes attrs;
188       // set portable attributes
189       attr.set_stack_size(4096*10);
190       // set non portable attribute
191       LPSECURITY_ATTRIBUTES sec;
192       // init sec 
193       attr.set_security(sec);
194       boost::thread th(attrs, find_the_question, 42);
195       // Set other thread attributes using the native_handle_type.
196       //...
197     #else
198     #error "Platform not supported"
199     #endif
200
201 [endsect]
202
203 [section:exceptions Exceptions in thread functions]
204
205 If the function or callable object passed to the __thread__ constructor propagates an exception when invoked that is not of type
206 __thread_interrupted__, `std::terminate()` is called. 
207
208 [endsect]
209
210 [section:detach Detaching thread]
211
212 A thread can  be detached by explicitly invoking the __detach__ member function on the __thread__
213 object. In this case, the __thread__ object ceases to represent the now-detached thread, and instead represents __not_a_thread__.
214
215   int main()
216   {
217     boost::thread t(my_func);
218     t.detach();
219   } 
220
221 [endsect]
222
223 [section:join Joining a thread]
224
225 In order to wait for a thread of execution to finish, the __join__, __join_for or __join_until (__timed_join__ deprecated) member functions of the __thread__ object must be
226 used. __join__ will block the calling thread until the thread represented by the __thread__ object has completed. 
227
228   int main()
229   {
230     boost::thread t(my_func);
231     t.join();
232   }
233
234
235 If the thread of
236 execution represented by the __thread__ object has already completed, or the __thread__ object represents __not_a_thread__, then __join__
237 returns immediately. 
238
239   int main()
240   {
241     boost::thread t;
242     t.join(); // do nothing
243   }
244
245 Timed based join are similar, except that a call to __join_for or __join_until will also return if the thread being waited for
246 does not complete when the specified time has elapsed or reached respectively.
247
248   int main()
249   {
250     boost::thread t;
251     if ( t.join_for(boost::chrono::milliseconds(500)) ) 
252       // do something else
253     t.join(); // join anyway
254   }
255
256 [endsect]
257
258 [section:destructor1 Destructor V1]
259
260 When the __thread__ object that represents a thread of execution is destroyed the thread becomes ['detached]. Once a thread is
261 detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed,
262 or the program is terminated. A thread can also be detached by explicitly invoking the __detach__ member function on the __thread__
263 object. In this case, the __thread__ object ceases to represent the now-detached thread, and instead represents __not_a_thread__.
264
265 [endsect]
266
267 [section:destructor2 Destructor V2]
268
269 When the __thread__ object that represents a thread of execution is destroyed the program terminates if the thread is __joinable__. 
270
271   int main()
272   {
273     boost::thread t(my_func);
274   } // calls std::terminate()
275
276 You can use a thread_joiner to ensure that the thread has been joined at the thread destructor.
277
278
279   int main()
280   {
281     boost::thread t(my_func);
282     boost::thread_joiner g(t);
283     // do someting else
284   } // here the thread_joiner destructor will join the thread before it is destroyed.
285
286 [endsect]
287
288 [section:interruption Interruption]
289
290 A running thread can be ['interrupted] by invoking the __interrupt__ member function of the corresponding __thread__ object. When the
291 interrupted thread next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing one)
292 with interruption enabled, then a __thread_interrupted__ exception will be thrown in the interrupted thread. If not caught,
293 this will cause the execution of the interrupted thread to terminate. As with any other exception, the stack will be unwound, and
294 destructors for objects of automatic storage duration will be executed.
295
296 If a thread wishes to avoid being interrupted, it can create an instance of __disable_interruption__. Objects of this class disable
297 interruption for the thread that created them on construction, and restore the interruption state to whatever it was before on
298 destruction:
299
300     void f()
301     {
302         // interruption enabled here
303         {
304             boost::this_thread::disable_interruption di;
305             // interruption disabled
306             {
307                 boost::this_thread::disable_interruption di2;
308                 // interruption still disabled
309             } // di2 destroyed, interruption state restored
310             // interruption still disabled
311         } // di destroyed, interruption state restored
312         // interruption now enabled
313     }
314
315 The effects of an instance of __disable_interruption__ can be temporarily reversed by constructing an instance of
316 __restore_interruption__, passing in the __disable_interruption__ object in question. This will
317 restore the interruption state to what it was when the __disable_interruption__ object was constructed, and then
318 disable interruption again when the __restore_interruption__ object is destroyed.
319
320     void g()
321     {
322         // interruption enabled here
323         {
324             boost::this_thread::disable_interruption di;
325             // interruption disabled
326             {
327                 boost::this_thread::restore_interruption ri(di);
328                 // interruption now enabled
329             } // ri destroyed, interruption disable again
330         } // di destroyed, interruption state restored
331         // interruption now enabled
332     }
333
334 At any point, the interruption state for the current thread can be queried by calling __interruption_enabled__.
335
336 [#interruption_points]
337
338 [heading Predefined Interruption Points]
339
340 The following functions are ['interruption points], which will throw __thread_interrupted__ if interruption is enabled for the
341 current thread, and interruption is requested for the current thread:
342
343 * [join_link `boost::thread::join()`]
344 * [timed_join_link `boost::thread::timed_join()`]
345 * `boost::__thread::__try_join_for()`,
346 * `boost::__thread::__try_join_until()`,
347 * [cond_wait_link `boost::condition_variable::wait()`]
348 * [cond_timed_wait_link `boost::condition_variable::timed_wait()`]
349 * `boost::__condition_variable::__wait_for()`
350 * `boost::__condition_variable::__wait_until()`
351 * [cond_any_wait_link `boost::condition_variable_any::wait()`]
352 * [cond_any_timed_wait_link `boost::condition_variable_any::timed_wait()`]
353 * `boost::__condition_variable_any::__cvany_wait_for()`
354 * `boost::__condition_variable_any::__cvany_wait_until()`
355 * [link thread.thread_management.thread.sleep `boost::thread::sleep()`]
356 * `boost::this_thread::__sleep_for()`
357 * `boost::this_thread::__sleep_until()`
358 * __interruption_point__
359
360 [endsect]
361
362 [section:id Thread IDs]
363
364 Objects of class __thread_id__ can be used to identify threads. Each running thread of execution has a unique ID obtainable
365 from the corresponding __thread__ by calling the `get_id()` member function, or by calling `boost::this_thread::get_id()` from
366 within the thread. Objects of class __thread_id__ can be copied, and used as keys in associative containers: the full range of
367 comparison operators is provided. Thread IDs can also be written to an output stream using the stream insertion operator, though the
368 output format is unspecified.
369
370 Each instance of __thread_id__ either refers to some thread, or __not_a_thread__. Instances that refer to __not_a_thread__
371 compare equal to each other, but not equal to any instances that refer to an actual thread of execution. The comparison operators on
372 __thread_id__ yield a total order for every non-equal thread ID.
373
374 [endsect]
375
376 [section:native_in Using native interfaces with Boost.Thread resources] 
377
378
379 __thread__ class has members `native_handle_type` and `native_handle` providing access to the underlying native handle.  
380          
381 This native handle can be used to change for example the scheduling. 
382
383 In general, it is not safe to use this handle with operations that can conflict with the ones provided by Boost.Thread. An example of bad usage could be detaching a thread directly as it will not change the internals of the __thread__ instance, so for example the joinable function will continue to return true, while the native thread is no more joinable. 
384
385   thread t(fct); 
386   thread::native_handle_type hnd=t.native_handle(); 
387   pthread_detach(hnd); 
388   assert(t.joinable()); 
389
390 [endsect]
391
392 [section:native_from Using Boost.Thread interfaces in a native thread] 
393  
394
395 Any thread of execution created using the native interface is called a native thread in this documentation. 
396
397 The first example of a native thread of execution is the main thread.  
398
399 The user can access to some synchronization functions related to the native current thread using the `boost::this_thread` `yield`, `sleep`, __sleep_for, __sleep_until, functions. 
400
401
402   int main() { 
403     // ... 
404     boost::this_thread::sleep_for(boost::chrono::milliseconds(10)); 
405     // ... 
406   } 
407
408
409 Of course all the synchronization facilities provided by Boost.Thread are also available on native threads. 
410
411 The `boost::this_thread` interrupt related functions behave in a degraded mode when called from a thread created using the native interface, i.e. `boost::this_thread::interruption_enabled()` returns false. As consequence the use of `boost::this_thread::disable_interruption` and `boost::this_thread::restore_interruption` will do nothing and calls to `boost::this_thread::interruption_point()` will be just ignored.  
412
413 As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` wiil returns false for the native threads. 
414
415 [heading `pthread_exit` POSIX limitation]
416
417 `pthread_exit` in glibc/NPTL causes a "forced unwind" that is almost like a C++ exception, but not quite. On Mac OS X, for example, `pthread_exit` unwinds without calling C++ destructors.
418
419 This behavior is incompatible with the current Boost.Thread design, so the use of this function in a POSIX thread result in undefined behavior of any Boost.Thread function.
420
421 [endsect]
422
423 [endsect] [/section:tutorial Tutorial]
424
425 [section:thread Class `thread`]
426
427     #include <boost/thread/thread.hpp>
428
429     class thread
430     {
431     public:
432         class attributes; // EXTENSION
433
434         thread() noexcept;
435         thread(const thread&) = delete;
436         thread& operator=(const thread&) = delete;
437
438         thread(thread&&) noexcept;
439         thread& operator=(thread&&) noexcept;
440         ~thread();
441
442         template <class F>
443         explicit thread(F f);
444         template <class F>
445         thread(F &&f);
446
447         template <class F,class A1,class A2,...>
448         thread(F f,A1 a1,A2 a2,...);
449         template <class F, class ...Args> 
450         explicit thread(F&& f, Args&&... args);
451
452         template <class F>
453         explicit thread(attributes& attrs, F f); // EXTENSION
454         template <class F>
455         thread(attributes& attrs, F &&f); // EXTENSION
456         template <class F, class ...Args> 
457         explicit thread(attributes& attrs, F&& f, Args&&... args);
458
459         // move support
460         thread(thread && x) noexcept;
461         thread& operator=(thread && x) noexcept;
462
463         void swap(thread& x) noexcept;
464
465         class id;
466
467         id get_id() const noexcept;
468
469         bool joinable() const noexcept;
470         void join();
471         template <class Rep, class Period>
472         bool try_join_for(const chrono::duration<Rep, Period>& rel_time); // EXTENSION
473         template <class Clock, class Duration>
474         bool try_join_until(const chrono::time_point<Clock, Duration>& t); // EXTENSION
475
476         void detach();
477
478         static unsigned hardware_concurrency() noexcept;
479         static unsigned physical_concurrency() noexcept;
480
481         typedef platform-specific-type native_handle_type;
482         native_handle_type native_handle();
483
484         void interrupt(); // EXTENSION
485         bool interruption_requested() const noexcept; // EXTENSION
486
487
488     #if defined BOOST_THREAD_USES_DATETIME
489         bool timed_join(const system_time& wait_until); // DEPRECATED
490         template<typename TimeDuration>
491         bool timed_join(TimeDuration const& rel_time); // DEPRECATED
492         static void sleep(const system_time& xt);// DEPRECATED
493     #endif
494
495     #if defined BOOST_THREAD_PROVIDES_THREAD_EQ
496         bool operator==(const thread& other) const; // DEPRECATED
497         bool operator!=(const thread& other) const; // DEPRECATED
498
499     #endif
500         static void yield() noexcept; // DEPRECATED
501
502     };
503
504     void swap(thread& lhs,thread& rhs) noexcept;
505
506 [section:default_constructor Default Constructor]
507
508     thread() noexcept;
509
510 [variablelist
511
512 [[Effects:] [Constructs a __thread__ instance that refers to __not_a_thread__.]]
513
514 [[Postconditions:] [`this->get_id()==thread::id()`]]
515
516 [[Throws:] [Nothing]]
517
518 ]
519
520 [endsect]
521
522 [section:move_constructor Move Constructor]
523
524     thread(thread&& other) noexcept;
525
526 [variablelist
527
528 [[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed __thread__ instance.]]
529
530 [[Postconditions:] [`other.get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the construction]]
531
532 [[Throws:] [Nothing]]
533
534 ]
535
536 [endsect]
537
538 [section:move_assignment Move assignment operator]
539
540     thread& operator=(thread&& other) noexcept;
541
542 [variablelist
543
544 [[Effects:] [Transfers ownership of the thread managed by `other` (if
545 any) to `*this`. 
546
547 - if defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable call __detach__, DEPRECATED
548
549 - if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to `std::terminate()`.
550 ]]
551
552 [[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
553
554 [[Throws:] [Nothing]]
555
556 ]
557
558
559 [endsect]
560
561 [section:callable_constructor Thread Constructor]
562
563     template<typename Callable>
564     thread(Callable func);
565
566 [variablelist
567
568 [[Requires:] [`Callable` must be Copyable and `func()` must be a valid expression.]]
569
570 [[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
571 thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
572 not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.]]
573
574 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
575
576 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
577
578 [[Error Conditions:] [
579
580 [*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded. 
581
582 ]]
583
584 ]
585
586 [endsect]
587
588 [section:attr_callable_constructor Thread Attributes Constructor EXTENSION]
589
590     template<typename Callable>
591     thread(attributes& attrs, Callable func);
592
593 [variablelist
594
595 [[Preconditions:] [`Callable` must be copyable.]]
596
597 [[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
598 thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
599 not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored. 
600 If the attributes declare the native thread as detached, the boost::thread will be detached.]]
601
602 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
603
604 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
605
606 [[Error Conditions:] [
607
608 [*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded. 
609
610 ]]
611
612 ]
613
614 [endsect]
615
616 [section:callable_move_constructor Thread Callable Move Constructor]
617
618     template<typename Callable>
619     thread(Callable &&func);
620
621 [variablelist
622
623 [[Preconditions:] [`Callable` must be Movable.]]
624
625 [[Effects:] [`func` is moved into storage managed internally by the thread library, and that copy is invoked on a newly-created
626 thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
627 not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.]]
628
629 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
630
631 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
632
633 [[Error Conditions:] [
634
635 [*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded. 
636
637 ]]
638
639 ]
640
641 [endsect]
642
643 [section:attr_callable_move_constructor Thread Attributes Move Constructor EXTENSION]
644
645     template<typename Callable>
646     thread(attributes& attrs, Callable func);
647
648 [variablelist
649
650 [[Preconditions:] [`Callable` must be copyable.]]
651
652 [[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
653 thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
654 not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored. 
655 If the attributes declare the native thread as detached, the boost::thread will be detached.]]
656
657 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
658
659 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
660
661 [[Error Conditions:] [
662
663 [*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded. 
664
665 ]]
666
667 ]
668
669 [endsect]
670
671
672 [section:multiple_argument_constructor Thread Constructor with arguments]
673
674     template <class F,class A1,class A2,...>
675     thread(F f,A1 a1,A2 a2,...);
676
677 [variablelist
678
679 [[Preconditions:] [`F` and each `A`n must be copyable or movable.]]
680
681 [[Effects:] [As if [link
682 thread.thread_management.thread.callable_constructor
683 `thread(boost::bind(f,a1,a2,...))`. Consequently, `f` and each `a`n
684 are copied into internal storage for access by the new thread.]]]
685
686 [[Postconditions:] [`*this` refers to the newly created thread of execution.]]
687
688 [[Throws:] [__thread_resource_error__ if an error occurs.]]
689
690 [[Error Conditions:] [
691
692 [*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded. 
693
694 ]]
695
696 [[Note:] [Currently up to nine additional arguments `a1` to `a9` can be specified in addition to the function `f`.]]
697
698 ]
699
700 [endsect]
701
702 [section:destructor Thread Destructor]
703
704     ~thread();
705
706
707 [variablelist
708
709 [[Effects:] [
710 - if defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls __detach__, DEPRECATED
711
712 - if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to `std::terminate`. Destroys `*this`.]]
713
714 [[Throws:] [Nothing.]]
715
716 [[Note:] [The reason to moving to std::terminate is that either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. Join the thread before destroying or use an scoped thread.]]
717
718 ]
719
720 [endsect]
721
722
723 [section:joinable Member function `joinable()`]
724
725     bool joinable() const noexcept;
726
727 [variablelist
728
729 [[Returns:] [`true` if `*this` refers to a thread of execution, `false` otherwise.]]
730
731 [[Throws:] [Nothing]]
732
733 ]
734
735
736 [endsect]
737
738 [section:join Member function `join()`]
739
740     void join();
741
742 [variablelist
743
744 [[Preconditions:] [the thread is joinable.]]
745
746 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete.]]
747
748 [[Synchronization:] [The completion of the thread represented by `*this` synchronizes with the
749 corresponding successful `join()` return. ]]
750 [[Note:] [Operations on *this are not synchronized.
751  ]]
752
753 [[Postconditions:] [If `*this` refers to a thread of execution on entry, that thread of execution has completed. `*this` no longer refers to any thread of execution.]]
754
755 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
756
757 [[Error Conditions:] [
758
759 [*resource_deadlock_would_occur]: if deadlock is detected or `this->get_id() == boost::this_thread::get_id()`.
760
761 [*invalid_argument]: if the thread is not joinable and `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined.
762
763
764 [/
765 [*no_such_process]: if the thread is not valid.
766
767
768
769 ]]
770
771 [[Notes:] [`join()` is one of the predefined __interruption_points__.]]
772
773 ]
774
775 [endsect]
776
777 [section:timed_join Member function `timed_join()` DEPRECATED]
778
779     bool timed_join(const system_time& wait_until);
780
781     template<typename TimeDuration>
782     bool timed_join(TimeDuration const& rel_time);
783
784 [warning
785 DEPRECATED since 3.00.
786  
787 Use instead __try_join_for, __try_join_until.  
788 ]
789
790 [variablelist
791
792 [[Preconditions:] [the thread is joinable.]]
793
794 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `wait_until` has
795 been reach or the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
796
797 [[Returns:] [`true` if `*this` refers to a thread of execution on entry, and that thread of execution has completed before the call
798 times out, `false` otherwise.]]
799
800 [[Postconditions:] [If `*this` refers to a thread of execution on entry, and `timed_join` returns `true`, that thread of execution
801 has completed, and `*this` no longer refers to any thread of execution. If this call to `timed_join` returns `false`, `*this` is
802 unchanged.]]
803
804 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
805
806 [[Error Conditions:] [
807
808 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
809
810 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
811
812
813 [/
814 [*no_such_process]: if the thread is not valid.
815
816
817 ]]
818
819 [[Notes:] [`timed_join()` is one of the predefined __interruption_points__.]]
820
821 ]
822
823 [endsect]
824
825 [section:try_join_for Member function `try_join_for()` EXTENSION]
826
827         template <class Rep, class Period>
828         bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
829
830 [variablelist
831
832 [[Preconditions:] [the thread is joinable.]]
833
834 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, 
835 the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
836
837 [[Returns:] [`true` if `*this` refers to a thread of execution on entry, and that thread of execution has completed before the call
838 times out, `false` otherwise.]]
839
840 [[Postconditions:] [If `*this` refers to a thread of execution on entry, and `try_join_for` returns `true`, that thread of execution
841 has completed, and `*this` no longer refers to any thread of execution. If this call to `try_join_for` returns `false`, `*this` is
842 unchanged.]]
843
844 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
845
846 [[Error Conditions:] [
847
848 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
849
850 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
851
852
853 [/
854 [*no_such_process]: if the thread is not valid.
855
856
857 ]]
858
859 [[Notes:] [`try_join_for()` is one of the predefined __interruption_points__.]]
860
861 ]
862
863 [endsect]
864
865 [section:try_join_until Member function `try_join_until()` EXTENSION]
866
867         template <class Clock, class Duration>
868         bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time);
869
870 [variablelist
871
872 [[Preconditions:] [the thread is joinable.]]
873
874 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `abs_time` has
875 been reach. If `*this` doesn't refer to a thread of execution, returns immediately.]]
876
877 [[Returns:] [`true` if `*this` refers to a thread of execution on entry, and that thread of execution has completed before the call
878 times out, `false` otherwise.]]
879
880 [[Postconditions:] [If `*this` refers to a thread of execution on entry, and `try_join_until` returns `true`, that thread of execution
881 has completed, and `*this` no longer refers to any thread of execution. If this call to `try_join_until` returns `false`, `*this` is
882 unchanged.]]
883
884 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
885
886 [[Error Conditions:] [
887
888 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
889
890 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
891
892
893 [/
894 [*no_such_process]: if the thread is not valid.
895
896
897
898 ]]
899
900 [[Notes:] [`try_join_until()` is one of the predefined __interruption_points__.]]
901
902 ]
903
904 [endsect]
905
906
907
908 [section:detach Member function `detach()`]
909
910     void detach();
911
912 [variablelist
913
914 [[Preconditions:] [the thread is joinable.]]
915
916 [[Effects:] [The thread of execution becomes detached, and no longer has an associated __thread__ object.]]
917
918 [[Postconditions:] [`*this` no longer refers to any thread of execution.]]
919
920 [[Throws:] [`system_error`]]
921
922 [[Error Conditions:] [
923
924 [*no_such_process]: if the thread is not valid.
925
926 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
927
928 ]]
929
930 ]
931
932 [endsect]
933
934
935 [section:get_id Member function `get_id()`]
936
937     thread::id get_id() const noexcept;
938
939 [variablelist
940
941 [[Returns:] [If `*this` refers to a thread of execution, an instance of __thread_id__ that represents that thread. Otherwise returns
942 a default-constructed __thread_id__.]]
943
944 [[Throws:] [Nothing]]
945
946 ]
947
948 [endsect]
949
950 [section:interrupt Member function `interrupt()` EXTENSION]
951
952     void interrupt();
953
954 [variablelist
955
956 [[Effects:] [If `*this` refers to a thread of execution, request that the thread will be interrupted the next time it enters one of
957 the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one of the
958 predefined __interruption_points__ with interruption enabled .]]
959
960 [[Throws:] [Nothing]]
961
962 ]
963         
964
965 [endsect]
966
967 [section:hardware_concurrency Static member function `hardware_concurrency()`]
968
969     unsigned hardware_concurrency() noexecpt;
970
971 [variablelist
972
973 [[Returns:] [The number of hardware threads available on the current system (e.g. number of CPUs or cores or hyperthreading units),
974 or 0 if this information is not available.]]
975
976 [[Throws:] [Nothing]]
977
978 ]
979
980 [endsect]
981
982 [section:physical_concurrency Static member function `physical_concurrency()`]
983
984     unsigned physical_concurrency() noexecpt;
985
986 [variablelist
987
988 [[Returns:] [The number of physical cores available on the current system. In contrast to `hardware_concurrency()` it does not return
989  the number of virtual cores, but it counts only physical cores.]]
990
991 [[Throws:] [Nothing]]
992
993 ]
994
995 [endsect]
996
997 [section:nativehandle Member function `native_handle()`]
998
999     typedef platform-specific-type native_handle_type;
1000     native_handle_type native_handle();
1001
1002 [variablelist
1003
1004 [[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
1005 implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
1006
1007 [[Throws:] [Nothing.]]
1008
1009 ]
1010
1011 [endsect]
1012
1013 [section:equals `operator==` DEPRECATED]
1014
1015     bool operator==(const thread& other) const;
1016
1017 [warning
1018 DEPRECATED since 4.0.0.  
1019  
1020 Use `a.__get_id()==b.__get_id()` instead`.
1021 ]
1022
1023
1024 [variablelist
1025
1026 [[Returns:] [`get_id()==other.get_id()`]]
1027
1028
1029 ]
1030
1031 [endsect]
1032
1033 [section:not_equals `operator!=` DEPRECATED]
1034
1035     bool operator!=(const thread& other) const;
1036
1037 [warning
1038 DEPRECATED since 4.0.0.  
1039  
1040 Use `a.__get_id()!=b.__get_id()` instead`.
1041 ]
1042
1043 [variablelist
1044
1045 [[Returns:] [`get_id()!=other.get_id()`]]
1046
1047 ]
1048
1049 [endsect]
1050
1051 [section:sleep Static member function `sleep()` DEPRECATED]
1052
1053     void sleep(system_time const& abs_time);
1054
1055 [warning
1056 DEPRECATED since 3.0.0.  
1057  
1058 Use `this_thread::__sleep_for()` or `this_thread::__sleep_until()`.
1059 ]
1060
1061
1062 [variablelist
1063
1064 [[Effects:] [Suspends the current thread until the specified time has been reached.]]
1065
1066 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
1067
1068 [[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
1069
1070 ]
1071
1072 [endsect]
1073
1074 [section:yield Static member function `yield()` DEPRECATED]
1075
1076     void yield();
1077
1078 [warning
1079 DEPRECATED since 3.0.0.  
1080  
1081 Use `this_thread::__yield()`.
1082 ]
1083
1084 [variablelist
1085
1086 [[Effects:] [See [link thread.thread_management.this_thread.yield `boost::this_thread::yield()`].]]
1087
1088 ]
1089
1090 [endsect]
1091
1092 [section:swap Member function `swap()`]
1093
1094     void swap(thread& other) noexcept;
1095
1096 [variablelist
1097
1098 [[Effects:] [Exchanges the threads of execution associated with `*this` and `other`, so `*this` is associated with the thread of
1099 execution associated with `other` prior to the call, and vice-versa.]]
1100
1101 [[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()` prior to the call. `other.get_id()` returns the same
1102 value as `this->get_id()` prior to the call.]]
1103
1104 [[Throws:] [Nothing.]]
1105
1106 ]
1107
1108 [endsect]
1109
1110 [section:non_member_swap Non-member function `swap()`]
1111
1112     #include <boost/thread/thread.hpp>
1113
1114     void swap(thread& lhs,thread& rhs) noexcept;
1115
1116 [variablelist
1117
1118 [[Effects:] [[link thread.thread_management.thread.swap `lhs.swap(rhs)`].]]
1119
1120 ]
1121
1122 [endsect]
1123
1124
1125 [section:id Class `boost::thread::id`]
1126
1127     #include <boost/thread/thread.hpp>
1128
1129     class thread::id
1130     {
1131     public:
1132         id() noexcept;
1133
1134         bool operator==(const id& y) const noexcept;
1135         bool operator!=(const id& y) const noexcept;
1136         bool operator<(const id& y) const noexcept;
1137         bool operator>(const id& y) const noexcept;
1138         bool operator<=(const id& y) const noexcept;
1139         bool operator>=(const id& y) const noexcept;
1140
1141         template<class charT, class traits>
1142         friend std::basic_ostream<charT, traits>& 
1143         operator<<(std::basic_ostream<charT, traits>& os, const id& x);
1144     };
1145
1146 [section:constructor Default constructor]
1147
1148     id() noexcept;
1149
1150 [variablelist
1151
1152 [[Effects:] [Constructs a __thread_id__ instance that represents __not_a_thread__.]]
1153
1154 [[Throws:] [Nothing]]
1155
1156 ]
1157
1158 [endsect]
1159
1160 [section:is_equal `operator==`]
1161
1162     bool operator==(const id& y) const noexcept;
1163
1164 [variablelist
1165
1166 [[Returns:] [`true` if `*this` and `y` both represent the same thread of execution, or both represent __not_a_thread__, `false`
1167 otherwise.]]
1168
1169 [[Throws:] [Nothing]]
1170
1171 ]
1172
1173 [endsect]
1174
1175 [section:not_equal `operator!=`]
1176
1177     bool operator!=(const id& y) const noexcept;
1178
1179 [variablelist
1180
1181 [[Returns:] [`true` if `*this` and `y` represent different threads of execution, or one represents a thread of execution, and
1182 the other represent __not_a_thread__, `false` otherwise.]]
1183
1184 [[Throws:] [Nothing]]
1185
1186 ]
1187
1188 [endsect]
1189
1190 [section:less_than `operator<`]
1191
1192     bool operator<(const id& y) const noexcept;
1193
1194 [variablelist
1195
1196 [[Returns:] [`true` if `*this!=y` is `true` and the implementation-defined total order of __thread_id__ values places `*this` before
1197 `y`, `false` otherwise.]]
1198
1199 [[Throws:] [Nothing]]
1200
1201 [[Note:] [A __thread_id__ instance representing __not_a_thread__ will always compare less than an instance representing a thread of
1202 execution.]]
1203
1204 ]
1205
1206 [endsect]
1207
1208
1209 [section:greater_than `operator>`]
1210
1211     bool operator>(const id& y) const noexcept;
1212
1213 [variablelist
1214
1215 [[Returns:] [`y<*this`]]
1216
1217 [[Throws:] [Nothing]]
1218
1219 ]
1220
1221 [endsect]
1222
1223 [section:less_than_or_equal `operator<=`]
1224
1225     bool operator<=(const id& y) const noexcept;
1226
1227 [variablelist
1228
1229 [[Returns:] [`!(y<*this)`]]
1230
1231 [[Throws:] [Nothing]]
1232
1233 ]
1234
1235 [endsect]
1236
1237 [section:greater_than_or_equal `operator>=`]
1238
1239     bool operator>=(const id& y) const noexcept;
1240
1241 [variablelist
1242
1243 [[Returns:] [`!(*this<y)`]]
1244
1245 [[Throws:] [Nothing]]
1246
1247 ]
1248
1249 [endsect]
1250
1251 [section:stream_out Friend `operator<<`]
1252
1253     template<class charT, class traits>
1254     friend std::basic_ostream<charT, traits>& 
1255     operator<<(std::basic_ostream<charT, traits>& os, const id& x);
1256
1257 [variablelist
1258
1259 [[Effects:] [Writes a representation of the __thread_id__ instance `x` to the stream `os`, such that the representation of two
1260 instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `a!=b`.]]
1261
1262 [[Returns:] [`os`]]
1263
1264 ]
1265
1266 [endsect]
1267
1268
1269 [endsect]
1270
1271 [section:attributes Class `boost::thread::attributes` EXTENSION]
1272
1273     class thread::attributes {
1274     public:
1275         attributes() noexcept;
1276         ~ attributes()=default;
1277         // stack
1278         void set_stack_size(std::size_t size) noexcept;
1279         std::size_t get_stack_size() const noexcept;
1280
1281     #if defined BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE
1282         typedef platform-specific-type native_handle_type;
1283         native_handle_type* native_handle() noexcept;
1284         const native_handle_type* native_handle() const noexcept;
1285     #endif
1286
1287     };
1288
1289 [section:constructor Default constructor]
1290
1291     thread_attributes() noexcept;
1292
1293 [variablelist
1294
1295 [[Effects:] [Constructs a thread atrributes instance with its default values.]]
1296
1297 [[Throws:] [Nothing]]
1298
1299 ]
1300
1301 [endsect]
1302
1303 [section: set_stack_size Member function `set_stack_size()`]
1304
1305         void set_stack_size(std::size_t size) noexcept;
1306
1307 [variablelist
1308
1309 [[Effects:] [Stores the stack size to be used to create a thread. This is an hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
1310
1311 [[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]
1312
1313 [[Throws:] [Nothing.]]
1314
1315 ]
1316
1317 [endsect]
1318
1319 [section:get_stack_size Member function `get_stack_size()`]
1320
1321         std::size_t get_stack_size() const noexcept;
1322
1323 [variablelist
1324
1325 [[Returns:] [The stack size to be used on the creation of a thread. Note that this function can return 0 meaning the default.]]
1326
1327 [[Throws:] [Nothing.]]
1328
1329 ]
1330
1331 [endsect]
1332
1333 [section:nativehandle Member function `native_handle()`]
1334
1335     typedef platform-specific-type native_handle_type;
1336         typedef platform-specific-type native_handle_type;
1337         native_handle_type* native_handle() noexcept;
1338         const native_handle_type* native_handle() const noexcept;
1339
1340 [variablelist
1341
1342 [[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
1343 thread attributes implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present and `BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE` is not defined.]]
1344
1345 [[Throws:] [Nothing.]]
1346
1347 ]
1348
1349 [endsect]
1350 [endsect] [/ thread::attributes ]
1351 [endsect] [/ thread ]
1352
1353 [section:this_thread Namespace `this_thread`]
1354
1355
1356   namespace boost {
1357     namespace this_thread {
1358       thread::id get_id() noexcept;
1359       template<typename TimeDuration>
1360       void yield() noexcept;
1361       template <class Clock, class Duration>
1362       void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 
1363       template <class Rep, class Period>
1364       void sleep_for(const chrono::duration<Rep, Period>& rel_time);
1365
1366       template<typename Callable>
1367       void at_thread_exit(Callable func); // EXTENSION
1368
1369       void interruption_point(); // EXTENSION
1370       bool interruption_requested() noexcept; // EXTENSION
1371       bool interruption_enabled() noexcept; // EXTENSION
1372       class disable_interruption; // EXTENSION
1373       class restore_interruption; // EXTENSION
1374
1375     #if defined BOOST_THREAD_USES_DATETIME
1376       void sleep(TimeDuration const& rel_time); // DEPRECATED
1377       void sleep(system_time const& abs_time);  // DEPRECATED
1378     #endif
1379     }
1380   }
1381
1382 [section:get_id Non-member function `get_id()`]
1383
1384     #include <boost/thread/thread.hpp>
1385
1386     namespace this_thread
1387     {
1388         thread::id get_id() noexcept;
1389     }
1390
1391 [variablelist
1392
1393 [[Returns:] [An instance of __thread_id__ that represents that currently executing thread.]]
1394
1395 [[Throws:] [__thread_resource_error__ if an error occurs.]]
1396
1397 ]
1398
1399 [endsect]
1400
1401 [section:interruption_point Non-member function `interruption_point()` EXTENSION]
1402
1403     #include <boost/thread/thread.hpp>
1404
1405     namespace this_thread
1406     {
1407         void interruption_point();
1408     }
1409
1410 [variablelist
1411
1412 [[Effects:] [Check to see if the current thread has been interrupted.]]
1413
1414 [[Throws:] [__thread_interrupted__ if __interruption_enabled__ and __interruption_requested__ both return `true`.]]
1415
1416 ]
1417
1418 [endsect]
1419
1420 [section:interruption_requested Non-member function `interruption_requested()` EXTENSION]
1421
1422     #include <boost/thread/thread.hpp>
1423
1424     namespace this_thread
1425     {
1426         bool interruption_requested() noexcept;
1427     }
1428
1429 [variablelist
1430
1431 [[Returns:] [`true` if interruption has been requested for the current thread, `false` otherwise.]]
1432
1433 [[Throws:] [Nothing.]]
1434
1435 ]
1436
1437 [endsect]
1438
1439 [section:interruption_enabled Non-member function `interruption_enabled()` EXTENSION]
1440
1441     #include <boost/thread/thread.hpp>
1442
1443     namespace this_thread
1444     {
1445         bool interruption_enabled() noexcept;
1446     }
1447
1448 [variablelist
1449
1450 [[Returns:] [`true` if interruption has been enabled for the current thread, `false` otherwise.]]
1451
1452 [[Throws:] [Nothing.]]
1453
1454 ]
1455
1456 [endsect]
1457
1458 [section:sleep Non-member function `sleep()` DEPRECATED]
1459
1460     #include <boost/thread/thread.hpp>
1461
1462     namespace this_thread
1463     {
1464         template<typename TimeDuration>
1465         void sleep(TimeDuration const& rel_time);
1466         void sleep(system_time const& abs_time)
1467     }
1468
1469 [warning
1470 DEPRECATED since 3.0.0.  
1471  
1472 Use `__sleep_for()` and `__sleep_until()` instead.
1473 ]
1474
1475
1476 [variablelist
1477
1478 [[Effects:] [Suspends the current thread until the time period
1479 specified by `rel_time` has elapsed or the time point specified by
1480 `abs_time` has been reached.]]
1481
1482 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
1483
1484 [[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
1485
1486 ]
1487
1488 [endsect]
1489
1490 [section:sleep_until Non-member function `sleep_until()`]
1491
1492     #include <boost/thread/thread.hpp>
1493
1494     namespace this_thread
1495     {
1496       template <class Clock, class Duration>
1497       void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 
1498       namespace no_interruption_point
1499       {
1500         template <class Clock, class Duration>
1501         void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 
1502       }
1503     }
1504
1505 [variablelist
1506
1507 [[Effects:] [Suspends the current thread until the time point specified by
1508 `abs_time` has been reached.]]
1509
1510 [[Throws:] [Nothing if Clock satisfies the TrivialClock requirements and operations of Duration
1511 do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted. ]]
1512
1513 [[Notes:] [`sleep_until()` is one of the predefined __interruption_points__.]]
1514 [[Notes:] [`no_interruption_point::sleep_until()` is NOT one of the __interruption_points__.]]
1515
1516 ]
1517
1518 [endsect]
1519
1520 [section:sleep_for Non-member function `sleep_for()`]
1521
1522     #include <boost/thread/thread.hpp>
1523
1524     namespace this_thread
1525     {
1526       template <class Rep, class Period>
1527       void sleep_for(const chrono::duration<Rep, Period>& rel_time);
1528       namespace no_interruption_point
1529       {
1530         template <class Rep, class Period>
1531         void sleep_for(const chrono::duration<Rep, Period>& rel_time);
1532       }
1533     }
1534
1535 [variablelist
1536
1537 [[Effects:] [Suspends the current thread until the duration specified by
1538 by `rel_time` has elapsed.]]
1539
1540 [[Throws:] [Nothing if operations of chrono::duration<Rep, Period> do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted.]]
1541
1542 [[Notes:] [`sleep_for()` is one of the predefined __interruption_points__.]]
1543 [[Notes:] [`no_interruption_point:: sleep_for()` is NOT one of the __interruption_points__.]]
1544
1545 ]
1546
1547 [endsect]
1548
1549
1550 [section:yield Non-member function `yield()`]
1551
1552     #include <boost/thread/thread.hpp>
1553
1554     namespace this_thread
1555     {
1556         void yield() noexcept;
1557     }
1558
1559 [variablelist
1560
1561 [[Effects:] [Gives up the remainder of the current thread's time slice, to allow other threads to run.]]
1562
1563 [[Throws:] [Nothing.]]
1564
1565 ]
1566
1567 [endsect]
1568
1569 [section:disable_interruption Class `disable_interruption` EXTENSION]
1570
1571     #include <boost/thread/thread.hpp>
1572
1573     namespace this_thread
1574     {
1575         class disable_interruption
1576         {
1577         public:
1578             disable_interruption(const disable_interruption&) = delete;
1579             disable_interruption& operator=(const disable_interruption&) = delete;
1580             disable_interruption() noexcept;
1581             ~disable_interruption() noexcept;
1582         };
1583     }
1584
1585 `boost::this_thread::disable_interruption` disables interruption for the current thread on construction, and restores the prior
1586 interruption state on destruction. Instances of `disable_interruption` cannot be copied or moved.
1587
1588 [section:constructor Constructor]
1589
1590     disable_interruption() noexcept;
1591
1592 [variablelist
1593
1594 [[Effects:] [Stores the current state of __interruption_enabled__ and disables interruption for the current thread.]]
1595
1596 [[Postconditions:] [__interruption_enabled__ returns `false` for the current thread.]]
1597
1598 [[Throws:] [Nothing.]]
1599
1600 ]
1601
1602 [endsect]
1603
1604 [section:destructor Destructor]
1605
1606     ~disable_interruption() noexcept;
1607
1608 [variablelist
1609
1610 [[Preconditions:] [Must be called from the same thread from which `*this` was constructed.]]
1611
1612 [[Effects:] [Restores the current state of __interruption_enabled__ for the current thread to that prior to the construction of `*this`.]]
1613
1614 [[Postconditions:] [__interruption_enabled__ for the current thread returns the value stored in the constructor of `*this`.]]
1615
1616 [[Throws:] [Nothing.]]
1617
1618 ]
1619
1620 [endsect]
1621
1622 [endsect]
1623
1624 [section:restore_interruption Class `restore_interruption` EXTENSION]
1625
1626     #include <boost/thread/thread.hpp>
1627
1628     namespace this_thread
1629     {
1630         class restore_interruption
1631         {
1632         public:
1633             restore_interruption(const restore_interruption&) = delete;
1634             restore_interruption& operator=(const restore_interruption&) = delete;
1635             explicit restore_interruption(disable_interruption& disabler) noexcept;
1636             ~restore_interruption() noexcept;
1637         };
1638     }
1639
1640 On construction of an instance of `boost::this_thread::restore_interruption`, the interruption state for the current thread is
1641 restored to the interruption state stored by the constructor of the supplied instance of __disable_interruption__. When the instance
1642 is destroyed, interruption is again disabled. Instances of `restore_interruption` cannot be copied or moved.
1643
1644 [section:constructor Constructor]
1645
1646     explicit restore_interruption(disable_interruption& disabler) noexcept;
1647
1648 [variablelist
1649
1650 [[Preconditions:] [Must be called from the same thread from which `disabler` was constructed.]]
1651
1652 [[Effects:] [Restores the current state of __interruption_enabled__ for the current thread to that prior to the construction of `disabler`.]]
1653
1654 [[Postconditions:] [__interruption_enabled__ for the current thread returns the value stored in the constructor of `disabler`.]]
1655
1656 [[Throws:] [Nothing.]]
1657
1658 ]
1659
1660 [endsect]
1661
1662 [section:destructor Destructor]
1663
1664     ~restore_interruption() noexcept;
1665
1666 [variablelist
1667
1668 [[Preconditions:] [Must be called from the same thread from which `*this` was constructed.]]
1669
1670 [[Effects:] [Disables interruption for the current thread.]]
1671
1672 [[Postconditions:] [__interruption_enabled__ for the current thread returns `false`.]]
1673
1674 [[Throws:] [Nothing.]]
1675
1676 ]
1677
1678 [endsect]
1679
1680 [endsect]
1681
1682 [section:atthreadexit Non-member function template `at_thread_exit()` EXTENSION]
1683
1684     #include <boost/thread/thread.hpp>
1685
1686     template<typename Callable>
1687     void at_thread_exit(Callable func);
1688
1689 [variablelist
1690
1691 [[Effects:] [A copy of `func` is placed in
1692 thread-specific storage. This copy is invoked when the current thread
1693 exits (even if the thread has been interrupted).]]
1694
1695 [[Postconditions:] [A copy of `func` has been saved for invocation on thread exit.]]
1696
1697 [[Throws:] [`std::bad_alloc` if memory cannot be allocated for the copy of the function, __thread_resource_error__ if any other
1698 error occurs within the thread library. Any exception thrown whilst copying `func` into internal storage.]]
1699
1700 [[Note:] [This function is *not* called if the thread was terminated
1701 forcefully using platform-specific APIs, or if the thread is
1702 terminated due to a call to `exit()`, `abort()` or
1703 `std::terminate()`. In particular, returning from `main()` is
1704 equivalent to call to `exit()`, so will not call any functions
1705 registered with `at_thread_exit()`]]
1706
1707 ]
1708
1709 [endsect]
1710
1711 [endsect]
1712
1713 [section:threadgroup Class `thread_group` EXTENSION]
1714
1715     #include <boost/thread/thread.hpp>
1716
1717     class thread_group
1718     {
1719     public:
1720         thread_group(const thread_group&) = delete;
1721         thread_group& operator=(const thread_group&) = delete;
1722
1723         thread_group();
1724         ~thread_group();
1725
1726         template<typename F>
1727         thread* create_thread(F threadfunc);
1728         void add_thread(thread* thrd);
1729         void remove_thread(thread* thrd);
1730         bool is_this_thread_in();
1731         bool is_thread_in(thread* thrd);
1732         void join_all();
1733         void interrupt_all();
1734         int size() const;
1735     };
1736
1737 `thread_group` provides for a collection of threads that are related in some fashion. New threads can be added to the group with
1738 `add_thread` and `create_thread` member functions. `thread_group` is not copyable or movable.
1739
1740 [section:constructor Constructor]
1741
1742     thread_group();
1743
1744 [variablelist
1745
1746 [[Effects:] [Create a new thread group with no threads.]]
1747
1748 ]
1749
1750 [endsect]
1751
1752 [section:destructor Destructor]
1753
1754     ~thread_group();
1755
1756 [variablelist
1757
1758 [[Effects:] [Destroy `*this` and `delete` all __thread__ objects in the group.]]
1759
1760 ]
1761
1762 [endsect]
1763
1764 [section:create_thread Member function `create_thread()`]
1765
1766     template<typename F>
1767     thread* create_thread(F threadfunc);
1768
1769 [variablelist
1770
1771 [[Effects:] [Create a new __thread__ object as-if by `new thread(threadfunc)` and add it to the group.]]
1772
1773 [[Postcondition:] [`this->size()` is increased by one, the new thread is running.]]
1774
1775 [[Returns:] [A pointer to the new __thread__ object.]]
1776
1777 ]
1778
1779 [endsect]
1780
1781 [section:add_thread Member function `add_thread()`]
1782
1783     void add_thread(thread* thrd);
1784
1785 [variablelist
1786
1787 [[Precondition:] [The expression `delete thrd` is well-formed and will not result in undefined behaviour and `is_thread_in(thrd) == false`.]]
1788
1789 [[Effects:] [Take ownership of the __thread__ object pointed to by `thrd` and add it to the group.]]
1790
1791 [[Postcondition:] [`this->size()` is increased by one.]]
1792
1793 ]
1794
1795 [endsect]
1796
1797 [section:remove_thread Member function `remove_thread()`]
1798
1799     void remove_thread(thread* thrd);
1800
1801 [variablelist
1802
1803 [[Effects:] [If `thrd` is a member of the group, remove it without calling `delete`.]]
1804
1805 [[Postcondition:] [If `thrd` was a member of the group, `this->size()` is decreased by one.]]
1806
1807 ]
1808
1809 [endsect]
1810
1811 [section:join_all Member function `join_all()`]
1812
1813     void join_all();
1814
1815 [variablelist
1816
1817 [[Requires:] [`is_this_thread_in() == false`.]]
1818
1819 [[Effects:] [Call `join()` on each __thread__ object in the group.]]
1820
1821 [[Postcondition:] [Every thread in the group has terminated.]]
1822
1823 [[Note:] [Since __join__ is one of the predefined __interruption_points__, `join_all()` is also an interruption point.]]
1824
1825 ]
1826
1827 [endsect]
1828
1829 [section:is_this_thread_in Member function `is_this_thread_in()`]
1830
1831     bool is_this_thread_in();
1832
1833 [variablelist
1834
1835 [[Returns:] [true if there is a thread `th` in the group such that `th.get_id() == this_thread::get_id()`.]]
1836
1837
1838 ]
1839
1840 [endsect]
1841
1842 [section:is_thread_in Member function `is_thread_in()`]
1843
1844     bool is_thread_in(thread* thrd);
1845
1846 [variablelist
1847
1848 [[Returns:] [true if there is a thread `th` in the group such that `th.get_id() == thrd->get_id()`.]]
1849
1850
1851 ]
1852
1853 [endsect]
1854
1855 [section:interrupt_all Member function `interrupt_all()`]
1856
1857     void interrupt_all();
1858
1859 [variablelist
1860
1861 [[Effects:] [Call `interrupt()` on each __thread__ object in the group.]]
1862
1863 ]
1864
1865 [endsect]
1866
1867 [section:size Member function `size()`]
1868
1869     int size();
1870
1871 [variablelist
1872
1873 [[Returns:] [The number of threads in the group.]]
1874
1875 [[Throws:] [Nothing.]]
1876
1877 ]
1878
1879 [endsect]
1880
1881
1882 [endsect]
1883
1884 [endsect]