#ifndef THREAD_POOL_H #define THREAD_POOL_H #include #include #include #include #include #include #include #include #include #include // C++11 版的 线程池 namespace BeiChen { class ThreadsGuard { public: ThreadsGuard(std::vector &v) : _threads(v) {} ~ThreadsGuard() { for (size_t i = 0; i != _threads.size(); ++i) { if (_threads[i].joinable()) { _threads[i].join(); } } } private: // 屏蔽掉左值引用、右值引用 ThreadsGuard(ThreadsGuard &&tg) = delete; ThreadsGuard &operator=(ThreadsGuard &&tg) = delete; ThreadsGuard(const ThreadsGuard &) = delete; ThreadsGuard &operator=(const ThreadsGuard &) = delete; private: std::vector &_threads; }; class ThreadPool { public: typedef std::function task_type; public: explicit ThreadPool(int n = 0); ~ThreadPool() { stop(); _cond.notify_all(); } void stop() { _stop.store(true, std::memory_order_release); } template std::future::type> add(Function &&, Args &&...); private: ThreadPool(ThreadPool &&) = delete; ThreadPool &operator=(ThreadPool &&) = delete; ThreadPool(const ThreadPool &) = delete; ThreadPool &operator=(const ThreadPool &) = delete; private: std::atomic _stop; std::mutex _mtx; std::condition_variable _cond; std::queue _tasks; std::vector _threads; zl::ThreadsGuard _tg; }; // inline ThreadPool::ThreadPool(int n) : _stop(false), _tg(_threads) { // int nthreads = n; // if (nthreads <= 0) { // nthreads = std::thread::hardware_concurrency(); // nthreads = (nthreads == 0 ? 2 : nthreads); // } // for (int i = 0; i != nthreads; ++i) { // _threads.push_back(std::thread([this] { // while (!_stop.load(std::memory_order_acquire)) { // task_type task; // { // std::unique_lock ulk(this->_mtx); // this->_cond.wait(ulk, [this] { // return _stop.load(std::memory_order_acquire) || // !this->_tasks.empty(); // }); // if (_stop.load(std::memory_order_acquire)) // return; // task = std::move(this->_tasks.front()); // this->_tasks.pop(); // } // task(); // } // })); // } // } template std::future::type> ThreadPool::add(Function &&fcn, Args &&...args) { typedef typename std::result_of::type return_type; typedef std::packaged_task task; auto t = std::make_shared( std::bind(std::forward(fcn), std::forward(args)...)); auto ret = t->get_future(); { std::lock_guard lg(_mtx); if (_stop.load(std::memory_order_acquire)) throw std::runtime_error("thread pool has stopped"); _tasks.emplace([t] { (*t)(); }); } _cond.notify_one(); return ret; } } // namespace zl #endif /* THREAD_POOL_H */