scoped_thread.qbk 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. [/
  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).
  7. ]
  8. [section:ScopedThreads Scoped Threads]
  9. [heading Synopsis]
  10. //#include <boost/thread/scoped_thread.hpp>
  11. struct detach;
  12. struct join_if_joinable;
  13. struct interrupt_and_join_if_joinable;
  14. template <class CallableThread = join_if_joinable, class Thread = thread>
  15. class strict_scoped_thread;
  16. template <class CallableThread = join_if_joinable, class Thread = thread>
  17. class scoped_thread;
  18. template <class CallableThread, class Thread = thread>
  19. void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
  20. [section:motivation Motivation]
  21. 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.
  22. 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.
  23. [endsect]
  24. [section:tutorial Tutorial]
  25. 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.
  26. 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.
  27. boost::strict_scoped_thread<> t1((boost::thread(f)));
  28. //t1.detach(); // compile fails
  29. boost::scoped_thread<> t2((boost::thread(f)));
  30. t2.detach();
  31. [endsect]
  32. [section:thread_functors Free Thread Functors]
  33. //#include <boost/thread/scoped_thread.hpp>
  34. struct detach;
  35. struct join_if_joinable;
  36. struct interrupt_and_join_if_joinable;
  37. [section:detach Functor `detach`]
  38. struct detach
  39. {
  40. template <class Thread>
  41. void operator()(Thread& t)
  42. {
  43. t.detach();
  44. }
  45. };
  46. [endsect]
  47. [section:join_if_joinable Functor `join_if_joinable`]
  48. struct join_if_joinable
  49. {
  50. template <class Thread>
  51. void operator()(Thread& t)
  52. {
  53. if (t.joinable())
  54. {
  55. t.join();
  56. }
  57. }
  58. };
  59. [endsect]
  60. [section:interrupt_and_join_if_joinable Functor `interrupt_and_join_if_joinable`]
  61. struct interrupt_and_join_if_joinable
  62. {
  63. template <class Thread>
  64. void operator()(Thread& t)
  65. {
  66. t.interrupt();
  67. if (t.joinable())
  68. {
  69. t.join();
  70. }
  71. }
  72. };
  73. [endsect]
  74. [endsect]
  75. [section:strict_scoped_thread Class `strict_scoped_thread`]
  76. // #include <boost/thread/scoped_thread.hpp>
  77. template <class CallableThread = join_if_joinable, class Thread = ::boost::thread>
  78. class strict_scoped_thread
  79. {
  80. thread t_; // for exposition purposes only
  81. public:
  82. strict_scoped_thread(strict_scoped_thread const&) = delete;
  83. strict_scoped_thread& operator=(strict_scoped_thread const&) = delete;
  84. explicit strict_scoped_thread(Thread&& t) noexcept;
  85. template <typename F&&, typename ...Args>
  86. explicit strict_scoped_thread(F&&, Args&&...);
  87. ~strict_scoped_thread();
  88. };
  89. RAII __thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
  90. CallableThread: A callable `void(thread&)`.
  91. The default is a `join_if_joinable`.
  92. Thread destructor terminates the program if the __thread is joinable.
  93. This wrapper can be used to join the thread before destroying it.
  94. [heading Example]
  95. boost::strict_scoped_thread<> t((boost::thread(F)));
  96. [section:default_constructor Constructor from a __thread]
  97. explicit strict_scoped_thread(Thread&& t) noexcept;
  98. [variablelist
  99. [[Effects:] [move the thread to own `t_`]]
  100. [[Throws:] [Nothing]]
  101. ]
  102. [endsect]
  103. [section:call_constructor Move Constructor from a Callable]
  104. template <typename F&&, typename ...Args>
  105. explicit strict_scoped_thread(F&&, Args&&...);
  106. [variablelist
  107. [[Effects:] [Construct an internal thread in place.]]
  108. [[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
  109. [[Throws:] [Any exception the thread construction can throw.]]
  110. ]
  111. [endsect]
  112. [section:destructor Destructor]
  113. ~strict_scoped_thread();
  114. [variablelist
  115. [[Effects:] [Equivalent to `CallableThread()(t_)`. ]]
  116. [[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
  117. ]
  118. [endsect]
  119. [endsect]
  120. [section:scoped_thread Class `scoped_thread`]
  121. #include <boost/thread/scoped_thread.hpp>
  122. template <class CallableThread, class Thread = thread>
  123. class scoped_thread
  124. {
  125. thread t_; // for exposition purposes only
  126. public:
  127. scoped_thread() noexcept;
  128. scoped_thread(const scoped_thread&) = delete;
  129. scoped_thread& operator=(const scoped_thread&) = delete;
  130. explicit scoped_thread(thread&& th) noexcept;
  131. template <typename F&&, typename ...Args>
  132. explicit scoped_thread(F&&, Args&&...);
  133. ~scoped_thread();
  134. // move support
  135. scoped_thread(scoped_thread && x) noexcept;
  136. scoped_thread& operator=(scoped_thread && x) noexcept;
  137. void swap(scoped_thread& x) noexcept;
  138. typedef thread::id id;
  139. id get_id() const noexcept;
  140. bool joinable() const noexcept;
  141. void join();
  142. #ifdef BOOST_THREAD_USES_CHRONO
  143. template <class Rep, class Period>
  144. bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
  145. template <class Clock, class Duration>
  146. bool try_join_until(const chrono::time_point<Clock, Duration>& t);
  147. #endif
  148. void detach();
  149. static unsigned hardware_concurrency() noexcept;
  150. static unsigned physical_concurrency() noexcept;
  151. typedef thread::native_handle_type native_handle_type;
  152. native_handle_type native_handle();
  153. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  154. void interrupt();
  155. bool interruption_requested() const noexcept;
  156. #endif
  157. };
  158. template <class CallableThread, class Thread = thread>
  159. void swap(scoped_thread<CallableThread,Thread>& lhs,scoped_thread<CallableThread,Thread>& rhs) noexcept;
  160. RAII __thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
  161. CallableThread: A callable void(thread&).
  162. The default is join_if_joinable.
  163. Thread destructor terminates the program if the thread is joinable.
  164. This wrapper can be used to join the thread before destroying it.
  165. Remark: `scoped_thread` is not a __thread as __thread is not designed to be derived from as a polymorphic type.
  166. Anyway `scoped_thread` can be used in most of the contexts a __thread could be used as it has the
  167. same non-deprecated interface with the exception of the construction.
  168. [heading Example]
  169. boost::scoped_thread<> t((boost::thread(F)));
  170. t.interrupt();
  171. [section:default_constructor Default Constructor]
  172. scoped_thread() noexcept;
  173. [variablelist
  174. [[Effects:] [Constructs a scoped_thread instance that wraps to __not_a_thread__.]]
  175. [[Postconditions:] [`this->get_id()==thread::id()`]]
  176. [[Throws:] [Nothing]]
  177. ]
  178. [endsect]
  179. [section:move_constructor Move Constructor]
  180. scoped_thread(scoped_thread&& other) noexcept;
  181. [variablelist
  182. [[Effects:] [Transfers ownership of the scoped_thread managed by `other` (if any) to the newly constructed scoped_thread instance.]]
  183. [[Postconditions:] [`other.get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the construction]]
  184. [[Throws:] [Nothing]]
  185. ]
  186. [endsect]
  187. [section:move_assignment Move assignment operator]
  188. scoped_thread& operator=(scoped_thread&& other) noexcept;
  189. [variablelist
  190. [[Effects:] [Transfers ownership of the scoped_thread managed by `other` (if
  191. any) to `*this` after having called to `CallableThread()(t_)`.
  192. ]]
  193. [[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
  194. [[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
  195. ]
  196. [endsect]
  197. [section:thread_constructor Move Constructor from a __thread]
  198. scoped_thread(thread&& t);
  199. [variablelist
  200. [[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed scoped_thread instance.]]
  201. [[Postconditions:] [other.get_id()==thread::id() and get_id() returns the value of other.get_id() prior to the construction.]]
  202. [[Throws:] [Nothing]]
  203. ]
  204. [endsect]
  205. [section:call_constructor Move Constructor from a Callable]
  206. template <typename F&&, typename ...Args>
  207. explicit scoped_thread(F&&, Args&&...);
  208. [variablelist
  209. [[Effects:] [Construct an internal thread in place.]]
  210. [[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
  211. [[Throws:] [Any exception the thread construction can throw.]]
  212. ]
  213. [endsect]
  214. [section:destructor Destructor]
  215. ~scoped_thread();
  216. [variablelist
  217. [[Effects:] [Equivalent to `CallableThread()(t_)`. ]]
  218. [[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
  219. ]
  220. [endsect]
  221. [section:joinable Member function `joinable()`]
  222. bool joinable() const noexcept;
  223. [variablelist
  224. [[Returns:] [Equivalent to return t_.joinable().]]
  225. [[Throws:] [Nothing]]
  226. ]
  227. [endsect]
  228. [section:join Member function `join()`]
  229. void join();
  230. [variablelist
  231. [[Effects:] [Equivalent to t_.join().]]
  232. ]
  233. [endsect]
  234. [section:try_join_for Member function `try_join_for()`]
  235. template <class Rep, class Period>
  236. bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
  237. [variablelist
  238. [[Effects:] [Equivalent to return `t_.try_join_for(rel_time)`.]]
  239. ]
  240. [endsect]
  241. [section:try_join_until Member function `try_join_until()`]
  242. template <class Clock, class Duration>
  243. bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time);
  244. [variablelist
  245. [[Effects:] [Equivalent to return `t_.try_join_until(abs_time)`.]]
  246. ]
  247. [endsect]
  248. [section:detach Member function `detach()`]
  249. void detach();
  250. [variablelist
  251. [[Effects:] [Equivalent to `t_.detach()`.]]
  252. ]
  253. [endsect]
  254. [section:get_id Member function `get_id()`]
  255. thread::id get_id() const noexcept;
  256. [variablelist
  257. [[Effects:] [Equivalent to return `t_.get_id()`.]]
  258. ]
  259. [endsect]
  260. [section:interrupt Member function `interrupt()`]
  261. void interrupt();
  262. [variablelist
  263. [[Effects:] [Equivalent to `t_.interrupt()`.]]
  264. ]
  265. [endsect]
  266. [section:hardware_concurrency Static member function `hardware_concurrency()`]
  267. unsigned hardware_concurrency() noexecpt;
  268. [variablelist
  269. [[Effects:] [Equivalent to return `thread::hardware_concurrency()`.]]
  270. ]
  271. [endsect]
  272. [section:physical_concurrency Static member function `physical_concurrency()`]
  273. unsigned physical_concurrency() noexecpt;
  274. [variablelist
  275. [[Effects:] [Equivalent to return `thread::physical_concurrency()`.]]
  276. ]
  277. [endsect]
  278. [section:nativehandle Member function `native_handle()`]
  279. typedef thread::native_handle_type native_handle_type;
  280. native_handle_type native_handle();
  281. [variablelist
  282. [[Effects:] [Equivalent to return `t_.native_handle()`.]]
  283. ]
  284. [endsect]
  285. [section:swap Member function `swap()`]
  286. void swap(scoped_thread& other) noexcept;
  287. [variablelist
  288. [[Effects:] [Equivalent `t_.swap(other.t_)`.]]
  289. ]
  290. [endsect]
  291. [endsect]
  292. [section:non_member_swap Non-member function `swap(scoped_thread&,scoped_thread&)`]
  293. #include <boost/thread/scoped_thread.hpp>
  294. template <class CallableThread, class Thread = thread>
  295. void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
  296. [variablelist
  297. [[Effects:] [`lhs.swap(rhs)`.]]
  298. ]
  299. [endsect]
  300. [endsect]