2 (C) Copyright 2008-9 Anthony Williams.
3 (C) Copyright 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:ScopedThreads Scoped Threads]
13 //#include <boost/thread/scoped_thread.hpp>
16 struct join_if_joinable;
17 struct interrupt_and_join_if_joinable;
18 template <class CallableThread = join_if_joinable>
19 class strict_scoped_thread;
20 template <class CallableThread = join_if_joinable>
22 void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
24 [section:motivation Motivation]
25 Based on the scoped_thread class defined in C++ Concurrency in Action Boost.Thread defines a thread wrapper class that instead of calling terminate if the thread is joinable on destruction, call a specific action given as template parameter.
27 While the scoped_thread class defined in C++ Concurrency in Action is closer to strict_scoped_thread class that doesn't allows any change in the wrapped thread, Boost.Thread provides a class scoped_thread that provides the same non-deprecated interface as __thread.
31 [section:tutorial Tutorial]
33 Scoped Threads are wrappers around a thread that allows the user to state what to do at destruction time. One of the common uses is to join the thread at destruction time so this is the default behavior. This is the single difference respect to a thread. While thread call std::terminate() on the destructor if the thread is joinable, strict_scoped_thread<> or scoped_thread<> join the thread if joinable.
35 The difference between strict_scoped_thread and scoped_thread is that the strict_scoped_thread hides completely the owned thread and so the user can do nothing with the owned thread other than the specific action given as parameter, while scoped_thread provide the same interface as __thread and forwards all the operations.
37 boost::strict_scoped_thread<> t1((boost::thread(f)));
38 //t1.detach(); // compile fails
39 boost::scoped_thread<> t2((boost::thread(f)));
44 [section:thread_functors Free Thread Functors]
46 //#include <boost/thread/scoped_thread.hpp>
49 struct join_if_joinable;
50 struct interrupt_and_join_if_joinable;
53 [section:detach Functor `detach`]
57 void operator()(thread& t)
63 [section:join_if_joinable Functor `join_if_joinable`]
65 struct join_if_joinable
67 void operator()(thread& t)
78 [section:interrupt_and_join_if_joinable Functor `interrupt_and_join_if_joinable`]
80 struct interrupt_and_join_if_joinable
82 void operator()(thread& t)
95 [section:strict_scoped_thread Class `strict_scoped_thread`]
97 // #include <boost/thread/scoped_thread.hpp>
99 template <class CallableThread = join_if_joinable>
100 class strict_scoped_thread
102 thread t_; // for exposition purposes only
105 strict_scoped_thread(strict_scoped_thread const&) = delete;
106 strict_scoped_thread& operator=(strict_scoped_thread const&) = delete;
108 explicit strict_scoped_thread(thread&& t) noexcept;
109 template <typename F&&, typename ...Args>
110 explicit strict_scoped_thread(F&&, Args&&...);
112 ~strict_scoped_thread();
117 RAII __thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
119 CallableThread: A callable `void(thread&)`.
121 The default is a `join_if_joinable`.
124 Thread destructor terminates the program if the __thread is joinable.
125 This wrapper can be used to join the thread before destroying it.
129 boost::strict_scoped_thread<> t((boost::thread(F)));
131 [section:default_constructor Constructor from a __thread]
133 explicit strict_scoped_thread(thread&& t) noexcept;
137 [[Effects:] [move the thread to own `t_`]]
139 [[Throws:] [Nothing]]
146 [section:call_constructor Move Constructor from a Callable]
148 template <typename F&&, typename ...Args>
149 explicit strict_scoped_thread(F&&, Args&&...);
153 [[Effects:] [Construct an internal thread in place.]]
155 [[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
157 [[Throws:] [Any exception the thread construction can throw.]]
163 [section:destructor Destructor]
165 ~strict_scoped_thread();
169 [[Effects:] [Equivalent to `CallableThread()(t_)`. ]]
171 [[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
179 [section:scoped_thread Class `scoped_thread`]
181 #include <boost/thread/scoped_thread.hpp>
183 template <class CallableThread>
186 thread t_; // for exposition purposes only
188 scoped_thread() noexcept;
189 scoped_thread(const scoped_thread&) = delete;
190 scoped_thread& operator=(const scoped_thread&) = delete;
192 explicit scoped_thread(thread&& th) noexcept;
193 template <typename F&&, typename ...Args>
194 explicit scoped_thread(F&&, Args&&...);
199 scoped_thread(scoped_thread && x) noexcept;
200 scoped_thread& operator=(scoped_thread && x) noexcept;
202 void swap(scoped_thread& x) noexcept;
204 typedef thread::id id;
206 id get_id() const noexcept;
208 bool joinable() const noexcept;
210 #ifdef BOOST_THREAD_USES_CHRONO
211 template <class Rep, class Period>
212 bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
213 template <class Clock, class Duration>
214 bool try_join_until(const chrono::time_point<Clock, Duration>& t);
219 static unsigned hardware_concurrency() noexcept;
220 static unsigned physical_concurrency() noexcept;
222 typedef thread::native_handle_type native_handle_type;
223 native_handle_type native_handle();
225 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
227 bool interruption_requested() const noexcept;
233 void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
236 RAII __thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
238 CallableThread: A callable void(thread&).
239 The default is join_if_joinable.
241 Thread destructor terminates the program if the thread is joinable.
242 This wrapper can be used to join the thread before destroying it.
244 Remark: `scoped_thread` is not a __thread as __thread is not designed to be derived from as a polymorphic type.
246 Anyway `scoped_thread` can be used in most of the contexts a __thread could be used as it has the
247 same non-deprecated interface with the exception of the construction.
251 boost::scoped_thread<> t((boost::thread(F)));
255 [section:default_constructor Default Constructor]
257 scoped_thread() noexcept;
261 [[Effects:] [Constructs a scoped_thread instance that wraps to __not_a_thread__.]]
263 [[Postconditions:] [`this->get_id()==thread::id()`]]
265 [[Throws:] [Nothing]]
271 [section:move_constructor Move Constructor]
273 scoped_thread(scoped_thread&& other) noexcept;
277 [[Effects:] [Transfers ownership of the scoped_thread managed by `other` (if any) to the newly constructed scoped_thread instance.]]
279 [[Postconditions:] [`other.get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the construction]]
281 [[Throws:] [Nothing]]
287 [section:move_assignment Move assignment operator]
289 scoped_thread& operator=(scoped_thread&& other) noexcept;
293 [[Effects:] [Transfers ownership of the scoped_thread managed by `other` (if
294 any) to `*this` after having called to `CallableThread()(t_)`.
298 [[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
300 [[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
307 [section:thread_constructor Move Constructor from a __thread]
309 scoped_thread(thread&& t);
313 [[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed scoped_thread instance.]]
315 [[Postconditions:] [other.get_id()==thread::id() and get_id() returns the value of other.get_id() prior to the construction.]]
317 [[Throws:] [Nothing]]
323 [section:call_constructor Move Constructor from a Callable]
325 template <typename F&&, typename ...Args>
326 explicit scoped_thread(F&&, Args&&...);
330 [[Effects:] [Construct an internal thread in place.]]
332 [[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
334 [[Throws:] [Any exception the thread construction can throw.]]
341 [section:destructor Destructor]
347 [[Effects:] [Equivalent to `CallableThread()(t_)`. ]]
349 [[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
356 [section:joinable Member function `joinable()`]
358 bool joinable() const noexcept;
362 [[Returns:] [Equivalent to return t_.joinable().]]
364 [[Throws:] [Nothing]]
371 [section:join Member function `join()`]
377 [[Effects:] [Equivalent to t_.join().]]
383 [section:try_join_for Member function `try_join_for()`]
385 template <class Rep, class Period>
386 bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
390 [[Effects:] [Equivalent to return `t_.try_join_for(rel_time)`.]]
396 [section:try_join_until Member function `try_join_until()`]
398 template <class Clock, class Duration>
399 bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time);
403 [[Effects:] [Equivalent to return `t_.try_join_until(abs_time)`.]]
411 [section:detach Member function `detach()`]
417 [[Effects:] [Equivalent to `t_.detach()`.]]
424 [section:get_id Member function `get_id()`]
426 thread::id get_id() const noexcept;
430 [[Effects:] [Equivalent to return `t_.get_id()`.]]
436 [section:interrupt Member function `interrupt()`]
442 [[Effects:] [Equivalent to `t_.interrupt()`.]]
449 [section:hardware_concurrency Static member function `hardware_concurrency()`]
451 unsigned hardware_concurrency() noexecpt;
455 [[Effects:] [Equivalent to return `thread::hardware_concurrency()`.]]
462 [section:physical_concurrency Static member function `physical_concurrency()`]
464 unsigned physical_concurrency() noexecpt;
468 [[Effects:] [Equivalent to return `thread::physical_concurrency()`.]]
475 [section:nativehandle Member function `native_handle()`]
477 typedef thread::native_handle_type native_handle_type;
478 native_handle_type native_handle();
482 [[Effects:] [Equivalent to return `t_.native_handle()`.]]
488 [section:swap Member function `swap()`]
490 void swap(scoped_thread& other) noexcept;
494 [[Effects:] [Equivalent `t_.swap(other.t_)`.]]
503 [section:non_member_swap Non-member function `swap(scoped_thread&,scoped_thread&)`]
505 #include <boost/thread/scoped_thread.hpp>
507 void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
511 [[Effects:] [`lhs.swap(rhs)`.]]