话说这个线程池也写了好久了 ,做简单的东西的时候也在用,最近因为一个失误删掉了自己的一些文件导致重新写了一遍 所以贴出来,以防万一 并且跟大佬们交流
// // Created by cxhmyself on 18-4-10. // #include <condition_variable> //都需要与互斥量一起才能工作 #include <mutex> #include <queue> #include <thread> #include <memory> #include "../epoll/Epoll.h" //template <class T , class Container = std::deque<T> > // 模板的所有要定义在同一个文件里面 template<class T> class threadsafe_queue { public: threadsafe_queue() = default; threadsafe_queue(const threadsafe_queue &Q) { std::lock_guard<std::mutex> lk(mut); dq = Q.dq; } threadsafe_queue& operator=(const threadsafe_queue & ) = delete; void push(const T data) { std::lock_guard<std::mutex> lk(mut); dq.push(data); cond.notify_one(); } bool try_pop(T& value) { std::lock_guard<std::mutex> lk(mut); if( dq.empty() ) return false; value = dq.front(); dq.pop(); return true; } std::shared_ptr<T> try_pop() { std::lock_guard<std::mutex> lk(mut); if( dq.empty() ) return std::shared_ptr<T> (); std::shared_ptr<T> res( std::make_shared<T>(dq.front()) ); dq.pop(); return res; } void wait_and_pop(T& value) // 用来得到顶部数据以及线程安全 { std::unique_lock<std::mutex> lk(mut); cond.wait(lk, [this] {return !(this->dq).empty() ; } ); value = dq.front(); dq.pop(); } std::shared_ptr<T> wait_and_pop() { std::unique_lock<std::mutex> lk(mut); cond.wait(lk, [this] {return !(this->dq).empty() ; } ); std::shared_ptr<T> result{ std::make_shared<T>(dq.front()) }; dq.pop(); return result; } bool empty() { std::lock_guard<std::mutex> lk(mut); return dq.empty(); } private: //分别是互斥量 条件变量 和队列本身 std::queue<T> dq; std::mutex mut; std::condition_variable cond; }; #endif /*最简单的线程池*/ #ifndef STUDENTCHARGE_THREADPOOL_H #define STUDENTCHARGE_THREADPOOL_H /*思考如何加入任务 使其为一个单源*/ /*任务类 T */ template<typename T> class Thread_pool { void run() { while( !stop ) { /*获取任务 要求每一个对象必须拥有一个任务执行表 即get_task()方法必须存在 使用接口的方式实现 每个必须继承之*/ /*临时封装一个任务是为了接受不同的情况 当然这里好象是并不需要的*/ auto item = worker_queue.try_pop(); if( item.get() != nullptr ) { /*执行任务*/ (*(*item)).task(); if( this->epollPoint != nullptr ) (*epollPoint).resetOneShot((*(*item)).getfd()); } else { std::this_thread::yield(); } } } public: /*构造函数*/ Thread_pool(Epoll *e = nullptr) :stop(false) ,epollPoint(e) { sum_threads = std::thread::hardware_concurrency() - 1; /*启动所有的线程*/ try { for (int i = 0; i < sum_threads; ++i) thread_pool.push_back(std::thread(&Thread_pool::run, this)); } catch (...) { this->~Thread_pool(); throw ; } } /*析构函数*/ ~Thread_pool() { stop = true; for(int i = 0 ; i < sum_threads ; ++i) thread_pool[i].join(); } /*添加到任务队列*/ void add_task(T tt ) { this->worker_queue.push(tt); } void * getEpoll() { return this->epollPoint; } private: /* 请求队列 这里用的智能指针是指目标用户的所有的数据 因为任务可能多样性所以先传入整体数据 队列智能指针类型 */ threadsafe_queue< T > worker_queue; /*线程池*/ std::vector<std::thread> thread_pool; /*检测是否线程池被销毁 被销毁则清除所有的线程*/ bool stop; /*线程池数量*/ size_t sum_threads; /*这个属于独特的属性*/ Epoll * epollPoint; }; #endif //CURRICULUMDESIGN_THREADPOOL_H