#include #include #include #include #include #include class thread_pool { public: thread_pool(std::size_t size) : stop(false) { for (std::size_t i = 0; i < size; ++i) { workers.emplace_back([this] { spawn(); }); } } virtual ~thread_pool() { if (!stop) join(); } void post(std::function f) { { std::unique_lock lock(mutex); tasks.push(f); } condition.notify_one(); } void join() { { std::unique_lock lock(mutex); stop = true; } condition.notify_all(); for (std::size_t i = 0; i < workers.size(); ++i) { workers[i].join(); } } private: void spawn() { std::function task; bool task_queue_empty = tasks.empty(); while (!stop || !task_queue_empty) { bool task_valid = false; { std::unique_lock lock(mutex); condition.wait(lock, [this]() { return (!tasks.empty()) || (tasks.empty() && stop); }); if (!tasks.empty()) { task = std::move(tasks.front()); tasks.pop(); task_valid = true; } task_queue_empty = tasks.empty(); } if (task_valid) task(); } } public: std::vector workers; std::queue> tasks; std::mutex mutex; std::condition_variable condition; bool stop; }; inline void dispatch(thread_pool &pool, std::function f) { pool.post(f); }