thread_pool.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. //
  2. // thread_pool.hpp
  3. // ~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_THREAD_POOL_HPP
  11. #define ASIO_THREAD_POOL_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/noncopyable.hpp"
  17. #include "asio/detail/scheduler.hpp"
  18. #include "asio/detail/thread_group.hpp"
  19. #include "asio/execution_context.hpp"
  20. #include "asio/detail/push_options.hpp"
  21. namespace asio {
  22. /// A simple fixed-size thread pool.
  23. /**
  24. * The thread pool class is an execution context where functions are permitted
  25. * to run on one of a fixed number of threads.
  26. *
  27. * @par Submitting tasks to the pool
  28. *
  29. * To submit functions to the thread_pool, use the @ref asio::dispatch,
  30. * @ref asio::post or @ref asio::defer free functions.
  31. *
  32. * For example:
  33. *
  34. * @code void my_task()
  35. * {
  36. * ...
  37. * }
  38. *
  39. * ...
  40. *
  41. * // Launch the pool with four threads.
  42. * asio::thread_pool pool(4);
  43. *
  44. * // Submit a function to the pool.
  45. * asio::post(pool, my_task);
  46. *
  47. * // Submit a lambda object to the pool.
  48. * asio::post(pool,
  49. * []()
  50. * {
  51. * ...
  52. * });
  53. *
  54. * // Wait for all tasks in the pool to complete.
  55. * pool.join(); @endcode
  56. */
  57. class thread_pool
  58. : public execution_context
  59. {
  60. public:
  61. class executor_type;
  62. /// Constructs a pool with an automatically determined number of threads.
  63. ASIO_DECL thread_pool();
  64. /// Constructs a pool with a specified number of threads.
  65. ASIO_DECL thread_pool(std::size_t num_threads);
  66. /// Destructor.
  67. /**
  68. * Automatically stops and joins the pool, if not explicitly done beforehand.
  69. */
  70. ASIO_DECL ~thread_pool();
  71. /// Obtains the executor associated with the pool.
  72. executor_type get_executor() ASIO_NOEXCEPT;
  73. /// Stops the threads.
  74. /**
  75. * This function stops the threads as soon as possible. As a result of calling
  76. * @c stop(), pending function objects may be never be invoked.
  77. */
  78. ASIO_DECL void stop();
  79. /// Joins the threads.
  80. /**
  81. * This function blocks until the threads in the pool have completed. If @c
  82. * stop() is not called prior to @c join(), the @c join() call will wait
  83. * until the pool has no more outstanding work.
  84. */
  85. ASIO_DECL void join();
  86. private:
  87. friend class executor_type;
  88. struct thread_function;
  89. // The underlying scheduler.
  90. detail::scheduler& scheduler_;
  91. // The threads in the pool.
  92. detail::thread_group threads_;
  93. };
  94. /// Executor used to submit functions to a thread pool.
  95. class thread_pool::executor_type
  96. {
  97. public:
  98. /// Obtain the underlying execution context.
  99. thread_pool& context() const ASIO_NOEXCEPT;
  100. /// Inform the thread pool that it has some outstanding work to do.
  101. /**
  102. * This function is used to inform the thread pool that some work has begun.
  103. * This ensures that the thread pool's join() function will not return while
  104. * the work is underway.
  105. */
  106. void on_work_started() const ASIO_NOEXCEPT;
  107. /// Inform the thread pool that some work is no longer outstanding.
  108. /**
  109. * This function is used to inform the thread pool that some work has
  110. * finished. Once the count of unfinished work reaches zero, the thread
  111. * pool's join() function is permitted to exit.
  112. */
  113. void on_work_finished() const ASIO_NOEXCEPT;
  114. /// Request the thread pool to invoke the given function object.
  115. /**
  116. * This function is used to ask the thread pool to execute the given function
  117. * object. If the current thread belongs to the pool, @c dispatch() executes
  118. * the function before returning. Otherwise, the function will be scheduled
  119. * to run on the thread pool.
  120. *
  121. * @param f The function object to be called. The executor will make
  122. * a copy of the handler object as required. The function signature of the
  123. * function object must be: @code void function(); @endcode
  124. *
  125. * @param a An allocator that may be used by the executor to allocate the
  126. * internal storage needed for function invocation.
  127. */
  128. template <typename Function, typename Allocator>
  129. void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
  130. /// Request the thread pool to invoke the given function object.
  131. /**
  132. * This function is used to ask the thread pool to execute the given function
  133. * object. The function object will never be executed inside @c post().
  134. * Instead, it will be scheduled to run on the thread pool.
  135. *
  136. * @param f The function object to be called. The executor will make
  137. * a copy of the handler object as required. The function signature of the
  138. * function object must be: @code void function(); @endcode
  139. *
  140. * @param a An allocator that may be used by the executor to allocate the
  141. * internal storage needed for function invocation.
  142. */
  143. template <typename Function, typename Allocator>
  144. void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
  145. /// Request the thread pool to invoke the given function object.
  146. /**
  147. * This function is used to ask the thread pool to execute the given function
  148. * object. The function object will never be executed inside @c defer().
  149. * Instead, it will be scheduled to run on the thread pool.
  150. *
  151. * If the current thread belongs to the thread pool, @c defer() will delay
  152. * scheduling the function object until the current thread returns control to
  153. * the pool.
  154. *
  155. * @param f The function object to be called. The executor will make
  156. * a copy of the handler object as required. The function signature of the
  157. * function object must be: @code void function(); @endcode
  158. *
  159. * @param a An allocator that may be used by the executor to allocate the
  160. * internal storage needed for function invocation.
  161. */
  162. template <typename Function, typename Allocator>
  163. void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
  164. /// Determine whether the thread pool is running in the current thread.
  165. /**
  166. * @return @c true if the current thread belongs to the pool. Otherwise
  167. * returns @c false.
  168. */
  169. bool running_in_this_thread() const ASIO_NOEXCEPT;
  170. /// Compare two executors for equality.
  171. /**
  172. * Two executors are equal if they refer to the same underlying thread pool.
  173. */
  174. friend bool operator==(const executor_type& a,
  175. const executor_type& b) ASIO_NOEXCEPT
  176. {
  177. return &a.pool_ == &b.pool_;
  178. }
  179. /// Compare two executors for inequality.
  180. /**
  181. * Two executors are equal if they refer to the same underlying thread pool.
  182. */
  183. friend bool operator!=(const executor_type& a,
  184. const executor_type& b) ASIO_NOEXCEPT
  185. {
  186. return &a.pool_ != &b.pool_;
  187. }
  188. private:
  189. friend class thread_pool;
  190. // Constructor.
  191. explicit executor_type(thread_pool& p) : pool_(p) {}
  192. // The underlying thread pool.
  193. thread_pool& pool_;
  194. };
  195. } // namespace asio
  196. #include "asio/detail/pop_options.hpp"
  197. #include "asio/impl/thread_pool.hpp"
  198. #if defined(ASIO_HEADER_ONLY)
  199. # include "asio/impl/thread_pool.ipp"
  200. #endif // defined(ASIO_HEADER_ONLY)
  201. #endif // ASIO_THREAD_POOL_HPP