14#include <condition_variable>
56 template <
class F,
class... Args>
57 std::future<std::invoke_result_t<F, Args...>>
enqueue(F&& f, Args&&... args)
59 using ReturnType = std::invoke_result_t<F, Args...>;
61 auto task = std::make_shared<std::packaged_task<ReturnType()>>(
62 std::bind(std::forward<F>(f), std::forward<Args>(args)...));
64 std::future<ReturnType> res = task->get_future();
66 std::unique_lock lock(_queue_mutex);
69 throw std::runtime_error(
"enqueue on stopped ThreadPool");
73 _tasks.emplace([task] { (*task)(); });
74 _condition.notify_one();
84 std::unique_lock lock(_queue_mutex);
85 _done_condition.wait(lock, [
this] {
return _pending_tasks == 0; });
95 using Task = std::function<void()>;
97 std::vector<std::thread> _workers;
98 std::queue<Task> _tasks;
99 std::mutex _queue_mutex;
100 std::condition_variable _condition;
101 std::condition_variable _done_condition;
102 std::atomic<bool> _stop =
false;
103 std::atomic<unsigned> _pending_tasks = 0;
A simple thread pool implementation.
~ThreadPool()
Destroys the ThreadPool, joining all threads.
std::future< std::invoke_result_t< F, Args... > > enqueue(F &&f, Args &&... args)
Enqueues a task to be executed by the thread pool.
ThreadPool(const ThreadPool &)=delete
ThreadPool & operator=(const ThreadPool &)=delete
ThreadPool & operator=(ThreadPool &&)=delete
void wait()
Waits for all tasks in the thread pool to finish.
unsigned getAvailableThreads()
Returns the number of threads available for executing tasks.
ThreadPool(ThreadPool &&)=delete