CAFFE2中C++11实现的线程池
2017-05-17 16:48
351 查看
根据之前的总结,可以说用C++11的新特性设计一个线程池已经非常容易了,配合thread、mutex、condition_variable、lock、配以智能指针即安全又便捷,同时bind、functiond等搭配食用更佳。
caffe2是基于caffe的升级版,其中大量使用了C++的新特性,所以为了进一步熟悉这些新特性,不妨看看caffe2的一些实现。
caffe2是基于caffe的升级版,其中大量使用了C++的新特性,所以为了进一步熟悉这些新特性,不妨看看caffe2的一些实现。
#ifndef CAFFE2_UTILS_THREAD_POOL_H_ #define CAFFE2_UTILS_THREAD_POOL_H_ #include <condition_variable> #include <functional> #include <mutex> #include <queue> #include <thread> class TaskThreadPool{ private: std::queue< std::function< void() > > tasks_;//任务队列,function仿函数: //function对象是对C++中现有的可调用实体的一种类型安全的包裹,包括函数,lambda表达式,函数指针等函数对象。 std::vector<std::thread> threads_;//线程的容器---线程池 std::mutex mutex_; std::condition_variable condition_; std::condition_variable completed_; bool running_; bool complete_; std::size_t available_; std::size_t total_; public: /// @brief Constructor. explicit TaskThreadPool(std::size_t pool_size) : threads_(pool_size), running_(true), complete_(true),available_(pool_size), total_(pool_size) { for ( std::size_t i = 0; i < pool_size; ++i ) { threads_[i] = std::thread( std::bind(&TaskThreadPool::main_loop, this));//绑定类的成员函数需要传入this指针 } } /// @brief Destructor. ~TaskThreadPool() { // Set running flag to false then notify all threads. { std::unique_lock< std::mutex > lock(mutex_); running_ = false; condition_.notify_all(); } try { for (auto& t : threads_) { t.join();//对于容器中的每一个线程都等到他执行完毕,因为c++没有主动kill线程的机制 } } // Suppress all exceptions. catch (const std::exception&) {} } //将可用的任务加入任务队列 template <typename Task> void runTask(Task task) { std::unique_lock<std::mutex> lock(mutex_); // 任务队列有了任务,通知线程可以开始干活了 tasks_.push(std::function<void()>(task)); complete_ = false; condition_.notify_one(); } /// @brief Wait for queue to be empty void waitWorkComplete() { std::unique_lock<std::mutex> lock(mutex_); if (!complete_) completed_.wait(lock); } private: //线程池入口 void main_loop() { while (running_) { // 如果任务队列是空的,那就等着吧,直到队列中有task被push std::unique_lock<std::mutex> lock(mutex_); while (tasks_.empty() && running_) { condition_.wait(lock); } // 如果线程池不工作了,直接退出; if (!running_) break; { std::function< void() > task = tasks_.front();//从任务队列中弹出函数 tasks_.pop(); --available_;//相应地减少线程池中可用的线程个数 lock.unlock(); try { task();//线程执行任务 } catch ( const std::exception& ) {} //再次获取锁 lock.lock(); //线程执行完毕,线程池内可用线程+1s ++available_; if (tasks_.empty() && available_ == total_) { complete_ = true; completed_.notify_one(); } } } } }; #endif
相关文章推荐
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- CAFFE2中C++11实现的线程池
- 使用C++11 实现的线程池
- [C++11]半同步半异步线程池实现与分析
- 基于C++11 thread 实现线程池
- c++11线程池实现
- 【c++11 新特性应用】利用bind实现通用的混合任务线程池
- C++11简化线程池的实现
- C++11线程池的实现
- c++11实现一个半同步半异步线程池
- c++11线程池实现