#include #include #include #include #include #include #include #include #include struct ThreadPool { public: using Job = std::function; ThreadPool(unsigned int nof_threads) : nof_threads(nof_threads), active(0), finished(false), threads(nof_threads) { for (auto& t: threads) { t = std::thread([=]() { process_jobs(); }); } } ~ThreadPool() { { std::unique_lock lock(mutex); finished = true; } cv.notify_all(); for (auto& t: threads) { t.join(); } } void submit(Job job) { std::unique_lock lock(mutex); jobs.push_back(std::move(job)); cv.notify_one(); } private: unsigned int nof_threads; unsigned int active; bool finished; std::vector threads; std::mutex mutex; std::condition_variable cv; std::list jobs; void process_jobs() { for(;;) { Job job; /* fetch job */ { std::unique_lock lock(mutex); while (jobs.empty() && (active > 0 || !finished)) { cv.wait(lock); } if (jobs.empty() && active == 0 && finished) break; job = std::move(jobs.front()); jobs.pop_front(); ++active; } /* execute job */ job(); { std::unique_lock lock(mutex); --active; } } /* if one thread finishes, all others have to finish as well */ cv.notify_all(); } }; int main() { ThreadPool pool(2); pool.submit([&]() { pool.submit([&]() { pool.submit([]() { std::cout << "Hello guys, I'm " << std::this_thread::get_id() << std::endl;; }); std::cout << "Hi guys, I'm " << std::this_thread::get_id() << std::endl;; }); pool.submit([&]() { pool.submit([]() { std::cerr << "O wonder, I'm " << std::this_thread::get_id() << std::endl;; }); std::cerr << "Huhu guys, I'm " << std::this_thread::get_id() << std::endl;; }); std::cout << "Hi, this is thread " << std::this_thread::get_id() << std::endl;; }); }