50 class thread_pool_thread;
54 friend class thread_pool_thread;
58 struct no_threads : std::logic_error {
no_threads() : std::logic_error(
"neolib::thread_pool::no_threads") {} };
61 typedef std::vector<std::unique_ptr<i_thread>> thread_list;
76 std::pair<std::future<void>,
task_pointer>
run(std::function<
void()> aFunction, int32_t aPriority = 0);
78 std::pair<std::future<T>,
task_pointer> run(std::function<T()> aFunction, int32_t aPriority = 0);
88 std::recursive_mutex&
mutex()
const;
90 void steal_work(thread_pool_thread& aIdleThread);
91 void thread_gone_idle();
92 void thread_gone_busy();
94 mutable std::recursive_mutex iMutex;
95 std::atomic<bool> iIdle;
96 std::atomic<bool> iStopped;
97 std::size_t iMaxThreads;
99 mutable std::mutex iWaitMutex;
100 mutable std::condition_variable iWaitConditionVariable;
103 template <
typename T>
108 auto newTask = std::make_shared<function_task<T>>(aFunction);
109 start(newTask, aPriority);
110 return std::make_pair(newTask->get_future(), newTask);
113 template <
typename Container>
114 inline void parallel_apply(
thread_pool& aThreadPool, Container& aContainer, std::function<
void(
typename Container::value_type& aElement)> aFunction, std::size_t aMinimumParallelismCount = 0)
118 if (aContainer.size() < aMinimumParallelismCount)
120 for (
auto& e : aContainer)
124 auto subrange = aContainer.size() / aThreadPool.
max_threads();
127 auto next = aContainer.begin();
128 for (
auto left = aContainer.size(); left >= subrange; left -= subrange)
131 aThreadPool.
run([next, end, &aFunction]()
133 for (
auto i = next; i != end; ++i)
138 if (next != aContainer.end())
139 aThreadPool.
run([next, &aContainer, &aFunction]()
141 for (
auto i = next; i != aContainer.end(); ++i)
std::recursive_mutex & mutex() const
std::size_t active_threads() const
std::pair< std::future< void >, task_pointer > run(std::function< void()> aFunction, int32_t aPriority=0)
std::size_t max_threads() const
std::size_t total_threads() const
std::size_t available_threads() const
std::shared_ptr< i_task > task_pointer
void start(i_task &aTask, int32_t aPriority=0)
bool try_start(i_task &aTask, int32_t aPriority=0)
bool try_start(task_pointer aTask, int32_t aPriority=0)
static thread_pool & default_thread_pool()
void start(task_pointer aTask, int32_t aPriority=0)
void reserve(std::size_t aMaxThreads)
void parallel_apply(thread_pool &aThreadPool, Container &aContainer, std::function< void(typename Container::value_type &aElement)> aFunction, std::size_t aMinimumParallelismCount=0)
it_type next(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)