最近在写MySQL冷备server的一个模块,稍微接触到一点线程池的东西,自己也就想尝试写一个简单的线程池练练手。
这个线程池在创建时,即按照最大的线程数生成线程。
然后作业任务通过add_task接口往线程池中加入需要运行的任务,再调用线程池的run函数开始运行所有任务,每个线程从任务队列中读取任务,处理完一个任务后再读取新的任务,直到最终任务队列为空。
补充:再回头看这个设计,其实算不了线程池,最多算是多线程执行任务。
把所有的任务描述信息先加入到CThreadPool的任务队列里面,然后调用CThreadPool的run函数去创建指定数量的线程,每个线程互斥的从任务队列里面取出任务去执行。
1 线程池设计
简单描述如下(假设任务类名为CTasklet):
1、CThreadPool<CTasklet> thread_pool(MAX_THREAD_NUM);
2、创建任务,并把任务加入到线程池
CTasklet *pTask1 = new CTasklet();
CTasklet *pTask2 = new CTasklet();
...
thread_pool.add_task(pTask1);
thread_pool.add_task(pTask2);
...
3、调用线程池的run方法开始执行任务
thread_pool.run();
4、等待任务执行完成
thread_pool.join_thread();
2 源码
下面给出完整的线程池代码
1 /* 2 * file: thread_pool.h 3 * desc: 简单的线程池,一次性初始化任务队列和线程池。 4 * 5 */ 6 7 #ifndef _THREAD_POOL_H_ 8 #define _THREAD_POOL_H_ 9 10 #include <pthread.h> 11 #include <vector> 12 13 using namespace std; 14 15 template<typename workType> 16 class CThreadPool 17 { 18 public: 19 typedef void * (thread_func)(void *); 20 21 CThreadPool(int thread_num, size_t stack_size = 10485760); 22 ~CThreadPool(); 23 24 // 向任务队列中添加任务 25 int add_task(workType *pTask); 26 27 // 创建新线程并执行 28 int run(); 29 30 // 等待所有的线程执行结束 31 int join_thread(); 32 33 private: 34 int init_thread_attr(); 35 int destroy_thread_attr(); 36 37 int set_thread_stacksize(size_t stack_size); 38 int set_thread_joinable(); 39 40 protected: 41 // 线程池执行函数,必须为static 42 static void start_routine(void *para); 43 44 private: 45 pthread_attr_t attr_; 46 static pthread_mutex_t mutex_lock_; 47 static list<workType *> list_task_; 48 49 int thread_num_; // 最大线程数 50 vector<pthread_t> thread_id_vec_; 51 }; 52 #endif