#include #include #include #include #include #include #include class ThreadPool { public: ThreadPool(size_t numThreads) : stop(false) { for (size_t i = 0; i < numThreads; ++i) { workers.emplace_back([this] { while (true) { std::function task; // Lock the queue to retrieve the next task { std::unique_lock lock(queueMutex); condition.wait(lock, [this] { return stop || !tasks.empty(); }); if (stop && tasks.empty()) { return; } // Get the next task from the queue task = std::move(tasks.front()); tasks.pop(); } // Execute the task task(); } }); } } // Submit a task to the thread pool template void enqueue(F&& f) { { std::unique_lock lock(queueMutex); if (stop) { throw std::runtime_error("ThreadPool is stopped"); } tasks.push(std::function(std::forward(f))); } condition.notify_one(); } // Wait for all threads to finish executing their tasks void wait() { // Block until all tasks have been completed std::unique_lock lock(queueMutex); condition.wait(lock, [this] { return tasks.empty(); }); } // Destructor: join all threads ~ThreadPool() { { std::unique_lock lock(queueMutex); stop = true; } condition.notify_all(); for (std::thread& worker : workers) { worker.join(); // Ensure each thread finishes before destruction } } private: std::vector workers; std::queue> tasks; std::mutex queueMutex; std::condition_variable condition; bool stop; };