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).
9 [section:thread_management Thread Management]
11 [section:synopsis Synopsis]
13 #include <boost/thread/thread.hpp>
18 void swap(thread& lhs,thread& rhs) noexcept;
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
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);
36 template<typename Callable>
37 void at_thread_exit(Callable func); // EXTENSION
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
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
51 class thread_group; // EXTENSION
55 [endsect] [/section:synopsis Synopsis]
57 [section:tutorial Tutorial]
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
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.
66 boost::thread make_thread();
70 boost::thread some_thread=make_thread();
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.
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.]
81 [section:launching Launching threads]
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.
93 boost::thread copies_are_safe()
96 return boost::thread(x);
97 } // x is destroyed, but the newly-created thread has a copy, so this is OK
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
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:
109 void find_the_question(int the_answer);
111 boost::thread deep_thought_2(find_the_question,42);
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.
116 There is an unspecified limit on the number of additional arguments that can be passed.
120 [section:attributes Thread attributes]
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:
127 boost::thread::attributes attrs;
128 attrs.set_size(4096*10);
129 boost::thread deep_thought_2(attrs, find_the_question, 42);
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.
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.
138 On PThread platforms the user will need to get the thread attributes handle and use it for whatever attribute.
140 Next follows how the user could set the stack size and the scheduling policy on PThread platforms.
142 boost::thread::attributes attrs;
143 // set portable attributes
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);
152 #error "Boost threads unavailable on this platform"
154 boost::thread th(attrs, find_the_question, 42);
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
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.
164 class MyWinTthreadAttributes : boost::thread::attributes
167 void set_attributes(boost::thread::native_handle_type h)
169 // use any specific windows thread setting
173 #if defined(BOOST_THREAD_PLATFORM_WIN32)
175 MyWinTthreadAttributes attrs;
176 // set portable attributes
178 attr.set_stack_size(4096*10);
179 boost::thread th(attrs, find_the_question, 42);
181 #error "Platform not supported"
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;
193 attr.set_security(sec);
194 boost::thread th(attrs, find_the_question, 42);
195 // Set other thread attributes using the native_handle_type.
198 #error "Platform not supported"
203 [section:exceptions Exceptions in thread functions]
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.
210 [section:detach Detaching thread]
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__.
217 boost::thread t(my_func);
223 [section:join Joining a thread]
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.
230 boost::thread t(my_func);
236 execution represented by the __thread__ object has already completed, or the __thread__ object represents __not_a_thread__, then __join__
242 t.join(); // do nothing
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.
251 if ( t.join_for(boost::chrono::milliseconds(500)) )
253 t.join(); // join anyway
258 [section:destructor1 Destructor V1]
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__.
267 [section:destructor2 Destructor V2]
269 When the __thread__ object that represents a thread of execution is destroyed the program terminates if the thread is __joinable__.
273 boost::thread t(my_func);
274 } // calls std::terminate()
276 You can use a thread_joiner to ensure that the thread has been joined at the thread destructor.
281 boost::thread t(my_func);
282 boost::thread_joiner g(t);
284 } // here the thread_joiner destructor will join the thread before it is destroyed.
288 [section:interruption Interruption]
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.
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
302 // interruption enabled here
304 boost::this_thread::disable_interruption di;
305 // interruption disabled
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
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.
322 // interruption enabled here
324 boost::this_thread::disable_interruption di;
325 // interruption disabled
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
334 At any point, the interruption state for the current thread can be queried by calling __interruption_enabled__.
336 [#interruption_points]
338 [heading Predefined Interruption Points]
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:
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__
362 [section:id Thread IDs]
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.
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.
376 [section:native_in Using native interfaces with Boost.Thread resources]
379 __thread__ class has members `native_handle_type` and `native_handle` providing access to the underlying native handle.
381 This native handle can be used to change for example the scheduling.
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.
386 thread::native_handle_type hnd=t.native_handle();
388 assert(t.joinable());
392 [section:native_from Using Boost.Thread interfaces in a native thread]
395 Any thread of execution created using the native interface is called a native thread in this documentation.
397 The first example of a native thread of execution is the main thread.
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.
404 boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
409 Of course all the synchronization facilities provided by Boost.Thread are also available on native threads.
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.
413 As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` wiil returns false for the native threads.
415 [heading `pthread_exit` POSIX limitation]
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.
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.
423 [endsect] [/section:tutorial Tutorial]
425 [section:thread Class `thread`]
427 #include <boost/thread/thread.hpp>
432 class attributes; // EXTENSION
435 thread(const thread&) = delete;
436 thread& operator=(const thread&) = delete;
438 thread(thread&&) noexcept;
439 thread& operator=(thread&&) noexcept;
443 explicit thread(F f);
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);
453 explicit thread(attributes& attrs, F f); // EXTENSION
455 thread(attributes& attrs, F &&f); // EXTENSION
456 template <class F, class ...Args>
457 explicit thread(attributes& attrs, F&& f, Args&&... args);
460 thread(thread && x) noexcept;
461 thread& operator=(thread && x) noexcept;
463 void swap(thread& x) noexcept;
467 id get_id() const noexcept;
469 bool joinable() const noexcept;
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
478 static unsigned hardware_concurrency() noexcept;
479 static unsigned physical_concurrency() noexcept;
481 typedef platform-specific-type native_handle_type;
482 native_handle_type native_handle();
484 void interrupt(); // EXTENSION
485 bool interruption_requested() const noexcept; // EXTENSION
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
495 #if defined BOOST_THREAD_PROVIDES_THREAD_EQ
496 bool operator==(const thread& other) const; // DEPRECATED
497 bool operator!=(const thread& other) const; // DEPRECATED
500 static void yield() noexcept; // DEPRECATED
504 void swap(thread& lhs,thread& rhs) noexcept;
506 [section:default_constructor Default Constructor]
512 [[Effects:] [Constructs a __thread__ instance that refers to __not_a_thread__.]]
514 [[Postconditions:] [`this->get_id()==thread::id()`]]
516 [[Throws:] [Nothing]]
522 [section:move_constructor Move Constructor]
524 thread(thread&& other) noexcept;
528 [[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed __thread__ instance.]]
530 [[Postconditions:] [`other.get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the construction]]
532 [[Throws:] [Nothing]]
538 [section:move_assignment Move assignment operator]
540 thread& operator=(thread&& other) noexcept;
544 [[Effects:] [Transfers ownership of the thread managed by `other` (if
547 - if defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable call __detach__, DEPRECATED
549 - if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to `std::terminate()`.
552 [[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
554 [[Throws:] [Nothing]]
561 [section:callable_constructor Thread Constructor]
563 template<typename Callable>
564 thread(Callable func);
568 [[Requires:] [`Callable` must be Copyable and `func()` must be a valid expression.]]
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.]]
574 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
576 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
578 [[Error Conditions:] [
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.
588 [section:attr_callable_constructor Thread Attributes Constructor EXTENSION]
590 template<typename Callable>
591 thread(attributes& attrs, Callable func);
595 [[Preconditions:] [`Callable` must be copyable.]]
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.]]
602 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
604 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
606 [[Error Conditions:] [
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.
616 [section:callable_move_constructor Thread Callable Move Constructor]
618 template<typename Callable>
619 thread(Callable &&func);
623 [[Preconditions:] [`Callable` must be Movable.]]
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.]]
629 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
631 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
633 [[Error Conditions:] [
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.
643 [section:attr_callable_move_constructor Thread Attributes Move Constructor EXTENSION]
645 template<typename Callable>
646 thread(attributes& attrs, Callable func);
650 [[Preconditions:] [`Callable` must be copyable.]]
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.]]
657 [[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
659 [[Throws:] [__thread_resource_error__ if an error occurs. ]]
661 [[Error Conditions:] [
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.
672 [section:multiple_argument_constructor Thread Constructor with arguments]
674 template <class F,class A1,class A2,...>
675 thread(F f,A1 a1,A2 a2,...);
679 [[Preconditions:] [`F` and each `A`n must be copyable or movable.]]
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.]]]
686 [[Postconditions:] [`*this` refers to the newly created thread of execution.]]
688 [[Throws:] [__thread_resource_error__ if an error occurs.]]
690 [[Error Conditions:] [
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.
696 [[Note:] [Currently up to nine additional arguments `a1` to `a9` can be specified in addition to the function `f`.]]
702 [section:destructor Thread Destructor]
710 - if defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls __detach__, DEPRECATED
712 - if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to `std::terminate`. Destroys `*this`.]]
714 [[Throws:] [Nothing.]]
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.]]
723 [section:joinable Member function `joinable()`]
725 bool joinable() const noexcept;
729 [[Returns:] [`true` if `*this` refers to a thread of execution, `false` otherwise.]]
731 [[Throws:] [Nothing]]
738 [section:join Member function `join()`]
744 [[Preconditions:] [the thread is joinable.]]
746 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete.]]
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.
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.]]
755 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
757 [[Error Conditions:] [
759 [*resource_deadlock_would_occur]: if deadlock is detected or `this->get_id() == boost::this_thread::get_id()`.
761 [*invalid_argument]: if the thread is not joinable and `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined.
765 [*no_such_process]: if the thread is not valid.
771 [[Notes:] [`join()` is one of the predefined __interruption_points__.]]
777 [section:timed_join Member function `timed_join()` DEPRECATED]
779 bool timed_join(const system_time& wait_until);
781 template<typename TimeDuration>
782 bool timed_join(TimeDuration const& rel_time);
785 DEPRECATED since 3.00.
787 Use instead __try_join_for, __try_join_until.
792 [[Preconditions:] [the thread is joinable.]]
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.]]
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.]]
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
804 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
806 [[Error Conditions:] [
808 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
810 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
814 [*no_such_process]: if the thread is not valid.
819 [[Notes:] [`timed_join()` is one of the predefined __interruption_points__.]]
825 [section:try_join_for Member function `try_join_for()` EXTENSION]
827 template <class Rep, class Period>
828 bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
832 [[Preconditions:] [the thread is joinable.]]
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.]]
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.]]
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
844 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
846 [[Error Conditions:] [
848 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
850 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
854 [*no_such_process]: if the thread is not valid.
859 [[Notes:] [`try_join_for()` is one of the predefined __interruption_points__.]]
865 [section:try_join_until Member function `try_join_until()` EXTENSION]
867 template <class Clock, class Duration>
868 bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time);
872 [[Preconditions:] [the thread is joinable.]]
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.]]
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.]]
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
884 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
886 [[Error Conditions:] [
888 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
890 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
894 [*no_such_process]: if the thread is not valid.
900 [[Notes:] [`try_join_until()` is one of the predefined __interruption_points__.]]
908 [section:detach Member function `detach()`]
914 [[Preconditions:] [the thread is joinable.]]
916 [[Effects:] [The thread of execution becomes detached, and no longer has an associated __thread__ object.]]
918 [[Postconditions:] [`*this` no longer refers to any thread of execution.]]
920 [[Throws:] [`system_error`]]
922 [[Error Conditions:] [
924 [*no_such_process]: if the thread is not valid.
926 [*invalid_argument]: if the thread is not joinable and BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined.
935 [section:get_id Member function `get_id()`]
937 thread::id get_id() const noexcept;
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__.]]
944 [[Throws:] [Nothing]]
950 [section:interrupt Member function `interrupt()` EXTENSION]
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 .]]
960 [[Throws:] [Nothing]]
967 [section:hardware_concurrency Static member function `hardware_concurrency()`]
969 unsigned hardware_concurrency() noexecpt;
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.]]
976 [[Throws:] [Nothing]]
982 [section:physical_concurrency Static member function `physical_concurrency()`]
984 unsigned physical_concurrency() noexecpt;
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.]]
991 [[Throws:] [Nothing]]
997 [section:nativehandle Member function `native_handle()`]
999 typedef platform-specific-type native_handle_type;
1000 native_handle_type native_handle();
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.]]
1007 [[Throws:] [Nothing.]]
1013 [section:equals `operator==` DEPRECATED]
1015 bool operator==(const thread& other) const;
1018 DEPRECATED since 4.0.0.
1020 Use `a.__get_id()==b.__get_id()` instead`.
1026 [[Returns:] [`get_id()==other.get_id()`]]
1033 [section:not_equals `operator!=` DEPRECATED]
1035 bool operator!=(const thread& other) const;
1038 DEPRECATED since 4.0.0.
1040 Use `a.__get_id()!=b.__get_id()` instead`.
1045 [[Returns:] [`get_id()!=other.get_id()`]]
1051 [section:sleep Static member function `sleep()` DEPRECATED]
1053 void sleep(system_time const& abs_time);
1056 DEPRECATED since 3.0.0.
1058 Use `this_thread::__sleep_for()` or `this_thread::__sleep_until()`.
1064 [[Effects:] [Suspends the current thread until the specified time has been reached.]]
1066 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
1068 [[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
1074 [section:yield Static member function `yield()` DEPRECATED]
1079 DEPRECATED since 3.0.0.
1081 Use `this_thread::__yield()`.
1086 [[Effects:] [See [link thread.thread_management.this_thread.yield `boost::this_thread::yield()`].]]
1092 [section:swap Member function `swap()`]
1094 void swap(thread& other) noexcept;
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.]]
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.]]
1104 [[Throws:] [Nothing.]]
1110 [section:non_member_swap Non-member function `swap()`]
1112 #include <boost/thread/thread.hpp>
1114 void swap(thread& lhs,thread& rhs) noexcept;
1118 [[Effects:] [[link thread.thread_management.thread.swap `lhs.swap(rhs)`].]]
1125 [section:id Class `boost::thread::id`]
1127 #include <boost/thread/thread.hpp>
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;
1141 template<class charT, class traits>
1142 friend std::basic_ostream<charT, traits>&
1143 operator<<(std::basic_ostream<charT, traits>& os, const id& x);
1146 [section:constructor Default constructor]
1152 [[Effects:] [Constructs a __thread_id__ instance that represents __not_a_thread__.]]
1154 [[Throws:] [Nothing]]
1160 [section:is_equal `operator==`]
1162 bool operator==(const id& y) const noexcept;
1166 [[Returns:] [`true` if `*this` and `y` both represent the same thread of execution, or both represent __not_a_thread__, `false`
1169 [[Throws:] [Nothing]]
1175 [section:not_equal `operator!=`]
1177 bool operator!=(const id& y) const noexcept;
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.]]
1184 [[Throws:] [Nothing]]
1190 [section:less_than `operator<`]
1192 bool operator<(const id& y) const noexcept;
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.]]
1199 [[Throws:] [Nothing]]
1201 [[Note:] [A __thread_id__ instance representing __not_a_thread__ will always compare less than an instance representing a thread of
1209 [section:greater_than `operator>`]
1211 bool operator>(const id& y) const noexcept;
1215 [[Returns:] [`y<*this`]]
1217 [[Throws:] [Nothing]]
1223 [section:less_than_or_equal `operator<=`]
1225 bool operator<=(const id& y) const noexcept;
1229 [[Returns:] [`!(y<*this)`]]
1231 [[Throws:] [Nothing]]
1237 [section:greater_than_or_equal `operator>=`]
1239 bool operator>=(const id& y) const noexcept;
1243 [[Returns:] [`!(*this<y)`]]
1245 [[Throws:] [Nothing]]
1251 [section:stream_out Friend `operator<<`]
1253 template<class charT, class traits>
1254 friend std::basic_ostream<charT, traits>&
1255 operator<<(std::basic_ostream<charT, traits>& os, const id& x);
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`.]]
1271 [section:attributes Class `boost::thread::attributes` EXTENSION]
1273 class thread::attributes {
1275 attributes() noexcept;
1276 ~ attributes()=default;
1278 void set_stack_size(std::size_t size) noexcept;
1279 std::size_t get_stack_size() const noexcept;
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;
1289 [section:constructor Default constructor]
1291 thread_attributes() noexcept;
1295 [[Effects:] [Constructs a thread atrributes instance with its default values.]]
1297 [[Throws:] [Nothing]]
1303 [section: set_stack_size Member function `set_stack_size()`]
1305 void set_stack_size(std::size_t size) noexcept;
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.]]
1311 [[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]
1313 [[Throws:] [Nothing.]]
1319 [section:get_stack_size Member function `get_stack_size()`]
1321 std::size_t get_stack_size() const noexcept;
1325 [[Returns:] [The stack size to be used on the creation of a thread. Note that this function can return 0 meaning the default.]]
1327 [[Throws:] [Nothing.]]
1333 [section:nativehandle Member function `native_handle()`]
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;
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.]]
1345 [[Throws:] [Nothing.]]
1350 [endsect] [/ thread::attributes ]
1351 [endsect] [/ thread ]
1353 [section:this_thread Namespace `this_thread`]
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);
1366 template<typename Callable>
1367 void at_thread_exit(Callable func); // EXTENSION
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
1375 #if defined BOOST_THREAD_USES_DATETIME
1376 void sleep(TimeDuration const& rel_time); // DEPRECATED
1377 void sleep(system_time const& abs_time); // DEPRECATED
1382 [section:get_id Non-member function `get_id()`]
1384 #include <boost/thread/thread.hpp>
1386 namespace this_thread
1388 thread::id get_id() noexcept;
1393 [[Returns:] [An instance of __thread_id__ that represents that currently executing thread.]]
1395 [[Throws:] [__thread_resource_error__ if an error occurs.]]
1401 [section:interruption_point Non-member function `interruption_point()` EXTENSION]
1403 #include <boost/thread/thread.hpp>
1405 namespace this_thread
1407 void interruption_point();
1412 [[Effects:] [Check to see if the current thread has been interrupted.]]
1414 [[Throws:] [__thread_interrupted__ if __interruption_enabled__ and __interruption_requested__ both return `true`.]]
1420 [section:interruption_requested Non-member function `interruption_requested()` EXTENSION]
1422 #include <boost/thread/thread.hpp>
1424 namespace this_thread
1426 bool interruption_requested() noexcept;
1431 [[Returns:] [`true` if interruption has been requested for the current thread, `false` otherwise.]]
1433 [[Throws:] [Nothing.]]
1439 [section:interruption_enabled Non-member function `interruption_enabled()` EXTENSION]
1441 #include <boost/thread/thread.hpp>
1443 namespace this_thread
1445 bool interruption_enabled() noexcept;
1450 [[Returns:] [`true` if interruption has been enabled for the current thread, `false` otherwise.]]
1452 [[Throws:] [Nothing.]]
1458 [section:sleep Non-member function `sleep()` DEPRECATED]
1460 #include <boost/thread/thread.hpp>
1462 namespace this_thread
1464 template<typename TimeDuration>
1465 void sleep(TimeDuration const& rel_time);
1466 void sleep(system_time const& abs_time)
1470 DEPRECATED since 3.0.0.
1472 Use `__sleep_for()` and `__sleep_until()` instead.
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.]]
1482 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
1484 [[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
1490 [section:sleep_until Non-member function `sleep_until()`]
1492 #include <boost/thread/thread.hpp>
1494 namespace this_thread
1496 template <class Clock, class Duration>
1497 void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
1498 namespace no_interruption_point
1500 template <class Clock, class Duration>
1501 void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
1507 [[Effects:] [Suspends the current thread until the time point specified by
1508 `abs_time` has been reached.]]
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. ]]
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__.]]
1520 [section:sleep_for Non-member function `sleep_for()`]
1522 #include <boost/thread/thread.hpp>
1524 namespace this_thread
1526 template <class Rep, class Period>
1527 void sleep_for(const chrono::duration<Rep, Period>& rel_time);
1528 namespace no_interruption_point
1530 template <class Rep, class Period>
1531 void sleep_for(const chrono::duration<Rep, Period>& rel_time);
1537 [[Effects:] [Suspends the current thread until the duration specified by
1538 by `rel_time` has elapsed.]]
1540 [[Throws:] [Nothing if operations of chrono::duration<Rep, Period> do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted.]]
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__.]]
1550 [section:yield Non-member function `yield()`]
1552 #include <boost/thread/thread.hpp>
1554 namespace this_thread
1556 void yield() noexcept;
1561 [[Effects:] [Gives up the remainder of the current thread's time slice, to allow other threads to run.]]
1563 [[Throws:] [Nothing.]]
1569 [section:disable_interruption Class `disable_interruption` EXTENSION]
1571 #include <boost/thread/thread.hpp>
1573 namespace this_thread
1575 class disable_interruption
1578 disable_interruption(const disable_interruption&) = delete;
1579 disable_interruption& operator=(const disable_interruption&) = delete;
1580 disable_interruption() noexcept;
1581 ~disable_interruption() noexcept;
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.
1588 [section:constructor Constructor]
1590 disable_interruption() noexcept;
1594 [[Effects:] [Stores the current state of __interruption_enabled__ and disables interruption for the current thread.]]
1596 [[Postconditions:] [__interruption_enabled__ returns `false` for the current thread.]]
1598 [[Throws:] [Nothing.]]
1604 [section:destructor Destructor]
1606 ~disable_interruption() noexcept;
1610 [[Preconditions:] [Must be called from the same thread from which `*this` was constructed.]]
1612 [[Effects:] [Restores the current state of __interruption_enabled__ for the current thread to that prior to the construction of `*this`.]]
1614 [[Postconditions:] [__interruption_enabled__ for the current thread returns the value stored in the constructor of `*this`.]]
1616 [[Throws:] [Nothing.]]
1624 [section:restore_interruption Class `restore_interruption` EXTENSION]
1626 #include <boost/thread/thread.hpp>
1628 namespace this_thread
1630 class restore_interruption
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;
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.
1644 [section:constructor Constructor]
1646 explicit restore_interruption(disable_interruption& disabler) noexcept;
1650 [[Preconditions:] [Must be called from the same thread from which `disabler` was constructed.]]
1652 [[Effects:] [Restores the current state of __interruption_enabled__ for the current thread to that prior to the construction of `disabler`.]]
1654 [[Postconditions:] [__interruption_enabled__ for the current thread returns the value stored in the constructor of `disabler`.]]
1656 [[Throws:] [Nothing.]]
1662 [section:destructor Destructor]
1664 ~restore_interruption() noexcept;
1668 [[Preconditions:] [Must be called from the same thread from which `*this` was constructed.]]
1670 [[Effects:] [Disables interruption for the current thread.]]
1672 [[Postconditions:] [__interruption_enabled__ for the current thread returns `false`.]]
1674 [[Throws:] [Nothing.]]
1682 [section:atthreadexit Non-member function template `at_thread_exit()` EXTENSION]
1684 #include <boost/thread/thread.hpp>
1686 template<typename Callable>
1687 void at_thread_exit(Callable func);
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).]]
1695 [[Postconditions:] [A copy of `func` has been saved for invocation on thread exit.]]
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.]]
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()`]]
1713 [section:threadgroup Class `thread_group` EXTENSION]
1715 #include <boost/thread/thread.hpp>
1720 thread_group(const thread_group&) = delete;
1721 thread_group& operator=(const thread_group&) = delete;
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);
1733 void interrupt_all();
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.
1740 [section:constructor Constructor]
1746 [[Effects:] [Create a new thread group with no threads.]]
1752 [section:destructor Destructor]
1758 [[Effects:] [Destroy `*this` and `delete` all __thread__ objects in the group.]]
1764 [section:create_thread Member function `create_thread()`]
1766 template<typename F>
1767 thread* create_thread(F threadfunc);
1771 [[Effects:] [Create a new __thread__ object as-if by `new thread(threadfunc)` and add it to the group.]]
1773 [[Postcondition:] [`this->size()` is increased by one, the new thread is running.]]
1775 [[Returns:] [A pointer to the new __thread__ object.]]
1781 [section:add_thread Member function `add_thread()`]
1783 void add_thread(thread* thrd);
1787 [[Precondition:] [The expression `delete thrd` is well-formed and will not result in undefined behaviour and `is_thread_in(thrd) == false`.]]
1789 [[Effects:] [Take ownership of the __thread__ object pointed to by `thrd` and add it to the group.]]
1791 [[Postcondition:] [`this->size()` is increased by one.]]
1797 [section:remove_thread Member function `remove_thread()`]
1799 void remove_thread(thread* thrd);
1803 [[Effects:] [If `thrd` is a member of the group, remove it without calling `delete`.]]
1805 [[Postcondition:] [If `thrd` was a member of the group, `this->size()` is decreased by one.]]
1811 [section:join_all Member function `join_all()`]
1817 [[Requires:] [`is_this_thread_in() == false`.]]
1819 [[Effects:] [Call `join()` on each __thread__ object in the group.]]
1821 [[Postcondition:] [Every thread in the group has terminated.]]
1823 [[Note:] [Since __join__ is one of the predefined __interruption_points__, `join_all()` is also an interruption point.]]
1829 [section:is_this_thread_in Member function `is_this_thread_in()`]
1831 bool is_this_thread_in();
1835 [[Returns:] [true if there is a thread `th` in the group such that `th.get_id() == this_thread::get_id()`.]]
1842 [section:is_thread_in Member function `is_thread_in()`]
1844 bool is_thread_in(thread* thrd);
1848 [[Returns:] [true if there is a thread `th` in the group such that `th.get_id() == thrd->get_id()`.]]
1855 [section:interrupt_all Member function `interrupt_all()`]
1857 void interrupt_all();
1861 [[Effects:] [Call `interrupt()` on each __thread__ object in the group.]]
1867 [section:size Member function `size()`]
1873 [[Returns:] [The number of threads in the group.]]
1875 [[Throws:] [Nothing.]]