]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/thread/doc/thread_ref.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / thread / doc / thread_ref.qbk
CommitLineData
7c673cae
FG
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;
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
59The __thread__ class is responsible for launching and managing threads. Each __thread__ object represents a single thread of execution,
60or __not_a_thread__, and at most one __thread__ object represents a given thread of execution: objects of type __thread__ are not
61copyable.
62
63Objects of type __thread__ are movable, however, so they can be stored in move-aware containers, and returned from functions. This
64allows 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
75therefore meets the C++0x ['MoveConstructible] and ['MoveAssignable] concepts. With such compilers, __thread__ can therefore be used
76with containers that support those concepts.
77
78For other compilers, move support is provided with a move emulation layer, so containers must explicitly detect that move emulation
79layer. See <boost/thread/detail/move.hpp> for details.]
80
81[section:launching Launching threads]
82
83A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The
84object is then copied into internal storage, and invoked on the newly-created thread of execution. If the object must not (or
85cannot) 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
106If you wish to construct an instance of __thread__ with a function or callable object that requires arguments to be supplied,
107this 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
113The arguments are ['copied] into the internal thread structure: if a reference is required, use `boost::ref`, just as for references
114to callable functions.
115
116There is an unspecified limit on the number of additional arguments that can be passed.
117
118[endsect]
119
120[section:attributes Thread attributes]
121
122Thread launched in this way are created with implementation defined thread attributes as stack size, scheduling,
123priority, ... or any platform specific attributes. It is not evident how to provide a portable interface that allows
124the user to set the platform specific attributes. Boost.Thread stay in the middle road through the class
125thread::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_stack_size(4096*10);
129 boost::thread deep_thought_2(attrs, find_the_question, 42);
130
131Even for this simple attribute there could be portable issues as some platforms could require that the stack size
132should have a minimal size and/or be a multiple of a given page size.
133The library adapts the requested size to the platform constraints so that the user doesn't need to take care of it.
134
135This is the single attribute that is provided in a portable way. In order to set any other thread attribute at
136construction time the user needs to use non portable code.
137
138On PThread platforms the user will need to get the thread attributes handle and use it for whatever attribute.
139
140Next 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.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
156On Windows platforms it is not so simple as there is no type that compiles the thread attributes.
157There 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.
158Boost.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.
161The 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
205If 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
212A thread can be detached by explicitly invoking the __detach__ member function on the __thread__
213object. 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
225In 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
226used. __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
235If the thread of
236execution represented by the __thread__ object has already completed, or the __thread__ object represents __not_a_thread__, then __join__
237returns immediately.
238
239 int main()
240 {
241 boost::thread t;
242 t.join(); // do nothing
243 }
244
245Timed based join are similar, except that a call to __join_for or __join_until will also return if the thread being waited for
246does 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-2]
259
260When the __thread__ object that represents a thread of execution is destroyed the thread becomes ['detached]. Once a thread is
261detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed,
262or the program is terminated. A thread can also be detached by explicitly invoking the __detach__ member function on the __thread__
263object. 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 V3-X]
268
269When 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
276You 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 something else
284 } // here the thread_joiner destructor will join the thread before it is destroyed.
285
286[endsect]
287
288[section:interruption Interruption]
289
290A running thread can be ['interrupted] by invoking the __interrupt__ member function of the corresponding __thread__ object. When the
291interrupted thread next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing one)
292with interruption enabled, then a __thread_interrupted__ exception will be thrown in the interrupted thread. Unless this exception is
293caught inside the interrupted thread's thread-main function, the stack unwinding process (as with any other exception) causes the
294destructors with automatic storage duration to be executed. Unlike other exceptions, when __thread_interrupted__ is propagated out of
295thread-main function, this does not cause the call to `std::terminate`; the effect is as though the thread-main function has returned
296normally.
297
298If a thread wishes to avoid being interrupted, it can create an instance of __disable_interruption__. Objects of this class disable
299interruption for the thread that created them on construction, and restore the interruption state to whatever it was before on
300destruction:
301
302 void f()
303 {
304 // interruption enabled here
305 {
306 boost::this_thread::disable_interruption di;
307 // interruption disabled
308 {
309 boost::this_thread::disable_interruption di2;
310 // interruption still disabled
311 } // di2 destroyed, interruption state restored
312 // interruption still disabled
313 } // di destroyed, interruption state restored
314 // interruption now enabled
315 }
316
317The effects of an instance of __disable_interruption__ can be temporarily reversed by constructing an instance of
318__restore_interruption__, passing in the __disable_interruption__ object in question. This will
319restore the interruption state to what it was when the __disable_interruption__ object was constructed, and then
320disable interruption again when the __restore_interruption__ object is destroyed.
321
322 void g()
323 {
324 // interruption enabled here
325 {
326 boost::this_thread::disable_interruption di;
327 // interruption disabled
328 {
329 boost::this_thread::restore_interruption ri(di);
330 // interruption now enabled
331 } // ri destroyed, interruption disable again
332 } // di destroyed, interruption state restored
333 // interruption now enabled
334 }
335
336At any point, the interruption state for the current thread can be queried by calling __interruption_enabled__.
337
338[#interruption_points]
339
340[heading Predefined Interruption Points]
341
342The following functions are ['interruption points], which will throw __thread_interrupted__ if interruption is enabled for the
343current thread, and interruption is requested for the current thread:
344
345* [join_link `boost::thread::join()`]
346* [timed_join_link `boost::thread::timed_join()`]
347* `boost::__thread::__try_join_for()`,
348* `boost::__thread::__try_join_until()`,
349* [cond_wait_link `boost::condition_variable::wait()`]
350* [cond_timed_wait_link `boost::condition_variable::timed_wait()`]
351* `boost::__condition_variable::__wait_for()`
352* `boost::__condition_variable::__wait_until()`
353* [cond_any_wait_link `boost::condition_variable_any::wait()`]
354* [cond_any_timed_wait_link `boost::condition_variable_any::timed_wait()`]
355* `boost::__condition_variable_any::__cvany_wait_for()`
356* `boost::__condition_variable_any::__cvany_wait_until()`
357* [link thread.thread_management.thread.sleep `boost::thread::sleep()`]
358* `boost::this_thread::__sleep_for()`
359* `boost::this_thread::__sleep_until()`
360* __interruption_point__
361
362[endsect]
363
364[section:id Thread IDs]
365
366Objects of class __thread_id__ can be used to identify threads. Each running thread of execution has a unique ID obtainable
367from the corresponding __thread__ by calling the `get_id()` member function, or by calling `boost::this_thread::get_id()` from
368within the thread. Objects of class __thread_id__ can be copied, and used as keys in associative containers: the full range of
369comparison operators is provided. Thread IDs can also be written to an output stream using the stream insertion operator, though the
370output format is unspecified.
371
372Each instance of __thread_id__ either refers to some thread, or __not_a_thread__. Instances that refer to __not_a_thread__
373compare equal to each other, but not equal to any instances that refer to an actual thread of execution. The comparison operators on
374__thread_id__ yield a total order for every non-equal thread ID.
375
376[endsect]
377
378[section:native_in Using native interfaces with Boost.Thread resources]
379
380
381__thread__ class has members `native_handle_type` and `native_handle` providing access to the underlying native handle.
382
383This native handle can be used to change for example the scheduling.
384
385In 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
387 thread t(fct);
388 thread::native_handle_type hnd=t.native_handle();
389 pthread_detach(hnd);
390 assert(t.joinable());
391
392[endsect]
393
394[section:native_from Using Boost.Thread interfaces in a native thread]
395
396
397Any thread of execution created using the native interface is called a native thread in this documentation.
398
399The first example of a native thread of execution is the main thread.
400
401The 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.
402
403
404 int main() {
405 // ...
406 boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
407 // ...
408 }
409
410
411Of course all the synchronization facilities provided by Boost.Thread are also available on native threads.
412
413The `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.
414
415As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` will return false for the native threads.
416
417[heading `pthread_exit` POSIX limitation]
418
419`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.
420
421This 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.
422
423[endsect]
424
425[endsect] [/section:tutorial Tutorial]
426
427[section:thread Class `thread`]
428
429 #include <boost/thread/thread.hpp>
430
431 class thread
432 {
433 public:
434 class attributes; // EXTENSION
435
436 thread() noexcept;
437 ~thread();
438
439 thread(const thread&) = delete;
440 thread& operator=(const thread&) = delete;
441
442 // move support
443 thread(thread&&) noexcept;
444 thread& operator=(thread&&) noexcept;
445
446 template <class F>
447 explicit thread(F f);
448 template <class F>
449 thread(F &&f);
450
451 template <class F,class A1,class A2,...>
452 thread(F f,A1 a1,A2 a2,...);
453 template <class F, class ...Args>
454 explicit thread(F&& f, Args&&... args);
455
456 template <class F>
457 explicit thread(attributes& attrs, F f); // EXTENSION
458 template <class F>
459 thread(attributes& attrs, F &&f); // EXTENSION
460 template <class F, class ...Args>
461 explicit thread(attributes& attrs, F&& f, Args&&... args);
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
545any) 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
571thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
572not 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
598thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
599not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.
600If 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
626thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
627not 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
653thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
654not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.
655If 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
682thread.thread_management.thread.callable_constructor
683`thread(boost::bind(f,a1,a2,...))`. Consequently, `f` and each `a`n
684are 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 a 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
749corresponding 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
785DEPRECATED since 3.00.
786
787Use 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
795been 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
798times 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
801has completed, and `*this` no longer refers to any thread of execution. If this call to `timed_join` returns `false`, `*this` is
802unchanged.]]
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,
835the 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
838times 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
841has completed, and `*this` no longer refers to any thread of execution. If this call to `try_join_for` returns `false`, `*this` is
842unchanged.]]
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
875been 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
878times 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
881has completed, and `*this` no longer refers to any thread of execution. If this call to `try_join_until` returns `false`, `*this` is
882unchanged.]]
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
942a 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
957the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one of the
958predefined __interruption_points__ with interruption enabled. Otherwise do noting.]]
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() noexcept;
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),
974or 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() noexcept;
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
1005implementation. 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
1018DEPRECATED since 4.0.0.
1019
1020Use `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
1038DEPRECATED since 4.0.0.
1039
1040Use `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
1056DEPRECATED since 3.0.0.
1057
1058Use `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
1079DEPRECATED since 3.0.0.
1080
1081Use `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
1099execution 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
1102value 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`
1167otherwise.]]
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
1182the 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
1202execution.]]
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
1260instances 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 attributes 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 a 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
1343thread 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
1470DEPRECATED since 3.0.0.
1471
1472Use `__sleep_for()` and `__sleep_until()` instead.
1473]
1474
1475
1476[variablelist
1477
1478[[Effects:] [Suspends the current thread until the time period
1479specified 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
1511do 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
1538by `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
1586interruption 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
1640On construction of an instance of `boost::this_thread::restore_interruption`, the interruption state for the current thread is
1641restored to the interruption state stored by the constructor of the supplied instance of __disable_interruption__. When the instance
1642is 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
1692thread-specific storage. This copy is invoked when the current thread
1693exits (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
1698error 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
1701forcefully using platform-specific APIs, or if the thread is
1702terminated due to a call to `exit()`, `abort()` or
1703`std::terminate()`. In particular, returning from `main()` is
1704equivalent to call to `exit()`, so will not call any functions
1705registered 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]