c++11 线程池
1 #ifndef THREAD_POOL_H 2 #define THREAD_POOL_H 3 4 #include <vector> 5 #include <queue> 6 #include <memory> 7 #include <thread> 8 #include <mutex> 9 #include <condition_variable> 10 #include <future> 11 #include <functional> 12 #include <stdexcept> 13 14 class ThreadPool { 15 public: 16 ThreadPool(size_t); 17 template<class F, class... Args> 18 auto enqueue(F&& f, Args&&... args) 19 -> std::future<typename std::result_of<F(Args...)>::type>; 20 ~ThreadPool(); 21 private: 22 // need to keep track of threads so we can join them 23 std::vector< std::thread > workers; 24 // the task queue 25 std::queue< std::function<void()> > tasks; 26 27 // synchronization 28 std::mutex queue_mutex; 29 std::condition_variable condition; 30 bool stop; 31 }; 32 33 // the constructor just launches some amount of workers 34 inline ThreadPool::ThreadPool(size_t threads) 35 : stop(false) 36 { 37 for(size_t i = 0;i<threads;++i) 38 workers.emplace_back( 39 [this] 40 { 41 for(;;) 42 { 43 std::function<void()> task; 44 45 { 46 std::unique_lock<std::mutex> lock(this->queue_mutex); 47 this->condition.wait(lock, 48 [this]{ return this->stop || !this->tasks.empty(); }); 49 if(this->stop && this->tasks.empty()) 50 return; 51 task = std::move(this->tasks.front()); 52 this->tasks.pop(); 53 } 54 55 task(); 56 } 57 } 58 ); 59 } 60 61 // add new work item to the pool 62 template<class F, class... Args> 63 auto ThreadPool::enqueue(F&& f, Args&&... args) 64 -> std::future<typename std::result_of<F(Args...)>::type> 65 { 66 using return_type = typename std::result_of<F(Args...)>::type; 67 68 auto task = std::make_shared< std::packaged_task<return_type()> >( 69 std::bind(std::forward<F>(f), std::forward<Args>(args)...) 70 ); 71 72 std::future<return_type> res = task->get_future(); 73 { 74 std::unique_lock<std::mutex> lock(queue_mutex); 75 76 // don't allow enqueueing after stopping the pool 77 if(stop) 78 throw std::runtime_error("enqueue on stopped ThreadPool"); 79 80 tasks.emplace([task](){ (*task)(); }); 81 } 82 condition.notify_one(); 83 return res; 84 } 85 86 // the destructor joins all threads 87 inline ThreadPool::~ThreadPool() 88 { 89 { 90 std::unique_lock<std::mutex> lock(queue_mutex); 91 stop = true; 92 } 93 condition.notify_all(); 94 for(std::thread &worker: workers) 95 worker.join(); 96 } 97 98 #endif
使用:
1 #include <iostream> 2 #include <vector> 3 #include <chrono> 4 5 #include "ThreadPool.h" 6 7 int main() 8 { 9 10 ThreadPool pool(4); 11 std::vector< std::future<int> > results; 12 13 for(int i = 0; i < 8; ++i) { 14 results.emplace_back( 15 pool.enqueue([i] { 16 std::cout << "hello " << i << std::endl; 17 std::this_thread::sleep_for(std::chrono::seconds(1)); 18 std::cout << "world " << i << std::endl; 19 return i*i; 20 }) 21 ); 22 } 23 24 for(auto && result: results) 25 std::cout << result.get() << ' '; 26 std::cout << std::endl; 27 28 return 0; 29 }
链接: