#include #include #include #include #include #include #include class ThreadPool{ public: ThreadPool(int n_threads) : shutdown_ (false) { // Start threads threads_.reserve (n_threads); for (int i = 0; i < n_threads; ++i) threads_.emplace_back (std::bind (&ThreadPool::threadentry, this, i)); } ~ThreadPool(){ { // Unlock threads and send them shutdown signal std::unique_lock lock (lock_); shutdown_ = true; condition_.notify_all(); } for (auto& thread : threads_) thread.join(); } void execute (std::function func) { // queue a job and unblock a thread std::unique_lock lock (lock_); jobqueue_.emplace (std::move(func)); condition_.notify_one(); } private: void threadentry (int i) { std::function job; while (true){ { std::unique_lock lock (lock_); while (!shutdown_ && jobqueue_.empty()) condition_.wait (lock); if (jobqueue_.empty()) { std::cerr << "Thread " << i << " terminates" << std::endl; return; } std::cerr << "Thread " << i << " takes a job" << std::endl; job = std::move(jobqueue_.front()); jobqueue_.pop(); // release lock } // Execute the job job(); } } std::mutex lock_; std::condition_variable condition_; bool shutdown_; std::queue > jobqueue_; std::vector threads_; }; /////// TESTING BEGINS /////////////////// void task(int n){ std::this_thread::sleep_for (std::chrono::seconds(n)); } int main(){ // create threads ThreadPool p (10); // assign tasks for (int i = 1; i<10; ++i){ p.execute (std::bind (task, i)); } }