scheduling_policies.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*! \file
  2. * \brief Task scheduling policies.
  3. *
  4. * This file contains some fundamental scheduling policies for the pool class.
  5. * A scheduling policy is realized by a task container which controls the access to
  6. * the tasks. Fundamentally the container determines the order the tasks are processed
  7. * by the thread pool.
  8. * The task containers need not to be thread-safe because they are used by the pool
  9. * in thread-safe way.
  10. *
  11. * Copyright (c) 2005-2007 Philipp Henkel
  12. *
  13. * Use, modification, and distribution are subject to the
  14. * Boost Software License, Version 1.0. (See accompanying file
  15. * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  16. *
  17. * http://threadpool.sourceforge.net
  18. *
  19. */
  20. #ifndef THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED
  21. #define THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED
  22. #include <queue>
  23. #include <deque>
  24. #include "task_adaptors.hpp"
  25. namespace boost { namespace threadpool
  26. {
  27. /*! \brief SchedulingPolicy which implements FIFO ordering.
  28. *
  29. * This container implements a FIFO scheduling policy.
  30. * The first task to be added to the scheduler will be the first to be removed.
  31. * The processing proceeds sequentially in the same order.
  32. * FIFO stands for "first in, first out".
  33. *
  34. * \param Task A function object which implements the operator()(void).
  35. *
  36. */
  37. template <typename Task = task_func>
  38. class fifo_scheduler
  39. {
  40. public:
  41. typedef Task task_type; //!< Indicates the scheduler's task type.
  42. protected:
  43. std::deque<task_type> m_container; //!< Internal task container.
  44. public:
  45. /*! Adds a new task to the scheduler.
  46. * \param task The task object.
  47. * \return true, if the task could be scheduled and false otherwise.
  48. */
  49. bool push(task_type const & task)
  50. {
  51. m_container.push_back(task);
  52. return true;
  53. }
  54. /*! Removes the task which should be executed next.
  55. */
  56. void pop()
  57. {
  58. m_container.pop_front();
  59. }
  60. /*! Gets the task which should be executed next.
  61. * \return The task object to be executed.
  62. */
  63. task_type const & top() const
  64. {
  65. return m_container.front();
  66. }
  67. /*! Gets the current number of tasks in the scheduler.
  68. * \return The number of tasks.
  69. * \remarks Prefer empty() to size() == 0 to check if the scheduler is empty.
  70. */
  71. size_t size() const
  72. {
  73. return m_container.size();
  74. }
  75. /*! Checks if the scheduler is empty.
  76. * \return true if the scheduler contains no tasks, false otherwise.
  77. * \remarks Is more efficient than size() == 0.
  78. */
  79. bool empty() const
  80. {
  81. return m_container.empty();
  82. }
  83. /*! Removes all tasks from the scheduler.
  84. */
  85. void clear()
  86. {
  87. m_container.clear();
  88. }
  89. };
  90. /*! \brief SchedulingPolicy which implements LIFO ordering.
  91. *
  92. * This container implements a LIFO scheduling policy.
  93. * The last task to be added to the scheduler will be the first to be removed.
  94. * LIFO stands for "last in, first out".
  95. *
  96. * \param Task A function object which implements the operator()(void).
  97. *
  98. */
  99. template <typename Task = task_func>
  100. class lifo_scheduler
  101. {
  102. public:
  103. typedef Task task_type; //!< Indicates the scheduler's task type.
  104. protected:
  105. std::deque<task_type> m_container; //!< Internal task container.
  106. public:
  107. /*! Adds a new task to the scheduler.
  108. * \param task The task object.
  109. * \return true, if the task could be scheduled and false otherwise.
  110. */
  111. bool push(task_type const & task)
  112. {
  113. m_container.push_front(task);
  114. return true;
  115. }
  116. /*! Removes the task which should be executed next.
  117. */
  118. void pop()
  119. {
  120. m_container.pop_front();
  121. }
  122. /*! Gets the task which should be executed next.
  123. * \return The task object to be executed.
  124. */
  125. task_type const & top() const
  126. {
  127. return m_container.front();
  128. }
  129. /*! Gets the current number of tasks in the scheduler.
  130. * \return The number of tasks.
  131. * \remarks Prefer empty() to size() == 0 to check if the scheduler is empty.
  132. */
  133. size_t size() const
  134. {
  135. return m_container.size();
  136. }
  137. /*! Checks if the scheduler is empty.
  138. * \return true if the scheduler contains no tasks, false otherwise.
  139. * \remarks Is more efficient than size() == 0.
  140. */
  141. bool empty() const
  142. {
  143. return m_container.empty();
  144. }
  145. /*! Removes all tasks from the scheduler.
  146. */
  147. void clear()
  148. {
  149. m_container.clear();
  150. }
  151. };
  152. /*! \brief SchedulingPolicy which implements prioritized ordering.
  153. *
  154. * This container implements a scheduling policy based on task priorities.
  155. * The task with highest priority will be the first to be removed.
  156. * It must be possible to compare two tasks using operator<.
  157. *
  158. * \param Task A function object which implements the operator() and operator<. operator< must be a partial ordering.
  159. *
  160. * \see prio_thread_func
  161. *
  162. */
  163. template <typename Task = prio_task_func>
  164. class prio_scheduler
  165. {
  166. public:
  167. typedef Task task_type; //!< Indicates the scheduler's task type.
  168. protected:
  169. std::priority_queue<task_type> m_container; //!< Internal task container.
  170. public:
  171. /*! Adds a new task to the scheduler.
  172. * \param task The task object.
  173. * \return true, if the task could be scheduled and false otherwise.
  174. */
  175. bool push(task_type const & task)
  176. {
  177. m_container.push(task);
  178. return true;
  179. }
  180. /*! Removes the task which should be executed next.
  181. */
  182. void pop()
  183. {
  184. m_container.pop();
  185. }
  186. /*! Gets the task which should be executed next.
  187. * \return The task object to be executed.
  188. */
  189. task_type const & top() const
  190. {
  191. return m_container.top();
  192. }
  193. /*! Gets the current number of tasks in the scheduler.
  194. * \return The number of tasks.
  195. * \remarks Prefer empty() to size() == 0 to check if the scheduler is empty.
  196. */
  197. size_t size() const
  198. {
  199. return m_container.size();
  200. }
  201. /*! Checks if the scheduler is empty.
  202. * \return true if the scheduler contains no tasks, false otherwise.
  203. * \remarks Is more efficient than size() == 0.
  204. */
  205. bool empty() const
  206. {
  207. return m_container.empty();
  208. }
  209. /*! Removes all tasks from the scheduler.
  210. */
  211. void clear()
  212. {
  213. while(!m_container.empty())
  214. {
  215. m_container.pop();
  216. }
  217. }
  218. };
  219. } } // namespace boost::threadpool
  220. #endif // THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED