简单Linux C线程池2
线程池的原理及意义,请移步这篇博文:http://www.cnblogs.com/venow/archive/2012/11/22/2779667.html
下面,介绍的这个线程池与上面提到的那个线程池有一部分相似的地方。
主要区别为:
1、线程池中的每个线程都有自己的互斥量和条件变量,而不是线程池共享一个。
2、线程池中的线程在程序结束时,等待线程池中线程停止的机制不同。
该程序主要由两个文件构成,分别为ThreadPool.h和ThreadPool.cpp文件。
ThreadPool.h文件:
#define MAXT_IN_POOL 200 #define BUSY_THRESHOlD 0.5 #define MANAGE_INTREVAL 2 class ThreadPool; typedef void (*dispatch_fn)(void*); //线程函数参数 typedef struct tagThread { pthread_t thread_id; //线程ID pthread_mutex_t thread_mutex; //信号量 pthread_cond_t thread_cond; //条件变量 dispatch_fn do_job; //调用的函数,任务 void* args; //函数参数 ThreadPool *parent; //线程池指针 }_thread; //线程池 class ThreadPool { public: //================================================================================================ //函数名: ThreadPool //函数描述: 构造函数 //输入: [in] max_threads_in_pool 线程池最大线程数 //输入: [in] min_threads_in_pool 线程池最小问题数 //输出: 无 //返回: 无 //================================================================================================ ThreadPool(unsigned int max_threads_in_pool, unsigned int min_threads_in_pool = 2); ~ThreadPool(); //================================================================================================ //函数名: dispatch_threadpool //函数描述: 将任务加入线程池,由线程池进行分发 //输入: [in] dispatch_me 调用的函数地址 //输入: [in] dispatch_me 函数参数 //输出: 无 //返回: 无 //================================================================================================ void dispatch_threadpool(dispatch_fn dispatch_me, void* dispatch_me); private: pthread_mutex_t tp_mutex; //信号量 pthread_cond_t tp_idle; //线程池中线程有空闲线程的条件变量 pthread_cond_t tp_full; //线程池中线程为满的条件变量 pthread_cond_t tp_empty; //线程池中线程为空的条件变量 int tp_min; //线程池的最小线程数 int tp_max; //线程池的最大线程数 int tp_avail; //线程池中空闲的线程数 int tp_total; //线程池中已创建的线程数 _thread** tp_list; //指向线程池中所有空闲线程的参数的指针 bool tp_stop; //线程池是否已停止 //================================================================================================ //函数名: add_avail //函数描述: 加入空闲线程 //输入: [in] avail 线程的参数 //输出: 无 //返回: 成功:true,失败:false //================================================================================================ bool add_avail(_thread* avail); //================================================================================================ //函数名: work_thread //函数描述: 线程函数 //输入: [in] args 参数 //输出: 无 //返回: 无 //================================================================================================ static void* work_thread(void* args); //================================================================================================ //函数名: add_thread //函数描述: 添加一个线程 //输入: [in] dispatch_me 函数指针 //输入: [in] args 函数参数 //输出: 无 //返回: 无 //================================================================================================ bool add_thread(dispatch_fn dispatch_me, void* args); //================================================================================================ //函数名: syn_all //函数描述: 等待线程池中所有线程空闲 //输入: 无 //输出: 无 //返回: 无 //================================================================================================ void syn_all(); };
ThreadPool.cpp文件:
ThreadPool::ThreadPool(unsigned int max_threads_in_pool, unsigned int min_threads_in_pool) { pthread_t manage_id; if (min_threads_in_pool <= 0 || max_threads_in_pool < 0 || min_threads_in_pool > max_threads_in_pool || max_threads_in_pool > MAXT_IN_POOL) { return ; } tp_avail = 0; //初始化线程池 tp_total = 0; tp_min = min_threads_in_pool; tp_max = max_threads_in_pool; tp_stop = false; tp_list = (_thread * *) malloc(sizeof(void *) * max_threads_in_pool); if (NULL == tp_list) { return; } memset(tp_list, 0, sizeof(void *) * max_threads_in_pool); pthread_mutex_init(&tp_mutex, NULL); pthread_cond_init(&tp_idle, NULL); pthread_cond_init(&tp_full, NULL); pthread_cond_init(&tp_empty, NULL); } bool ThreadPool::add_avail(_thread* avail) { bool ret = false; pthread_mutex_lock(&tp_mutex); if (tp_avail < tp_max) { tp_list[tp_avail] = avail; tp_avail++; pthread_cond_signal(&tp_idle); //线程池中有线程为空闲 if (tp_avail >= tp_total) { pthread_cond_signal(&tp_full); //线程池中所有线程都为为空闲 } ret = true; } pthread_mutex_unlock(&tp_mutex); return ret; } void* ThreadPool::work_thread(void* args) { _thread* thread = (_thread*) args; ThreadPool *pool = thread->parent; while (pool->tp_stop == false) { thread->do_job(thread->args); pthread_mutex_lock(&thread->thread_mutex); //执行完任务之后,添加到空闲线程队列中 if (pool->add_avail(thread)) { pthread_cond_wait(&thread->thread_cond, &thread->thread_mutex); pthread_mutex_unlock(&thread->thread_mutex); } else { pthread_mutex_unlock(&thread->thread_mutex); pthread_mutex_destroy(&thread->thread_mutex); pthread_cond_destroy(&thread->thread_cond); free(thread); break; } } pthread_mutex_lock(&pool->tp_mutex); pool->tp_total--; if (pool->tp_total <= 0) { pthread_cond_signal(&pool->tp_empty); } pthread_mutex_unlock(&pool->tp_mutex); return NULL; } bool ThreadPool::add_thread(dispatch_fn dispatch_me, void* args) //添加一个线程 { _thread* thread = NULL; pthread_attr_t attr; thread = (_thread *) malloc(sizeof(_thread)); if (NULL == thread) { return false; } pthread_mutex_init(&thread->thread_mutex, NULL); pthread_cond_init(&thread->thread_cond, NULL); thread->do_job = dispatch_me; thread->args = args; thread->parent = this; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (pthread_create(&thread->thread_id, &attr, work_thread, (void *) thread) != 0) { pthread_mutex_destroy(&thread->thread_mutex); pthread_cond_destroy(&thread->thread_cond); pthread_attr_destroy(&attr); free(thread); return false; } tp_total++; return true; } void ThreadPool::dispatch_threadpool(dispatch_fn dispatch_me, void* args) { _thread* thread = NULL; pthread_mutex_lock(&tp_mutex); if (tp_avail <= 0 && tp_total >= tp_max) //无可用线程,而且线程数已达最大值,等待空闲线程 { pthread_cond_wait(&tp_idle, &tp_mutex); } if (tp_avail <= 0) //无可用线程,而且线程数未达最大值,添加线程 { if (!add_thread(dispatch_me, args)) { return; } } else //有可用线程 { tp_avail--; thread = tp_list[tp_avail]; tp_list[tp_avail] = NULL; thread->do_job = dispatch_me; thread->args = args; pthread_mutex_lock(&thread->thread_mutex); pthread_cond_signal(&thread->thread_cond); pthread_mutex_unlock(&thread->thread_mutex); } pthread_mutex_unlock(&tp_mutex); } void ThreadPool::syn_all() { if (tp_avail < tp_total) //等待线程池中所有线程都为空闲状态 { pthread_cond_wait(&tp_full, &tp_mutex); } tp_stop = true; int i = 0; for (i = 0; i < tp_avail; i++) //唤醒线程池中所有线程 { _thread *thread = tp_list[i]; pthread_mutex_lock(&thread->thread_mutex); pthread_cond_signal(&thread->thread_cond); pthread_mutex_unlock(&thread->thread_mutex); } if (tp_total > 0) { pthread_cond_wait(&tp_empty, &tp_mutex); //等待线程池中所有线程都结束 } } ThreadPool::~ThreadPool() { sleep(MANAGE_INTREVAL); pthread_mutex_lock(&tp_mutex); syn_all(); //等待线程池为空 int i = 0; for (i = 0; i < tp_total; i++) //资源释放 { free(tp_list[i]); tp_list[i] = NULL; } pthread_mutex_unlock(&tp_mutex); pthread_mutex_destroy(&tp_mutex); pthread_cond_destroy(&tp_idle); pthread_cond_destroy(&tp_full); pthread_cond_destroy(&tp_empty); free(tp_list); }