什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。
下面列出线程的一些重要的函数
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); void pthread_exit(void *retval); int pthread_mutex_destroy(pthread_mutex_t *mutex); int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond);
#include <pthread.h> typedef struct worker_node{ /*任务结点*/ void *(*process)(void *arg); void *arg; worker_node *next; }worker_node; typedef struct worker_queue{/*任务队列*/ private: worker_node * head ,*tail ; int cur_size ; pthread_cond_t ready ;/**保持同步*/ pthread_mutex_t mutex ; /**保持互斥信号*/ bool destroy ; public: worker_queue(); ~worker_queue(); int clean(); /*清空队列*/ int in_queue(const worker_node *node); /*任务入队*/ worker_node * out_queue(); /*任务出队*/ } worker_queue ; class pmulti{ private: pthread_t * threads ; unsigned int thread_num; mutable worker_queue * w_queue; bool is_init; bool is_destroy; enum {QUEUE_MAX_SIZE=100}; public: pmulti(); ~pmulti(); int init(unsigned int num=10); static void * thread_fun(void *arg); /*线程执行主函数*/ int add_worker(const worker_node * node); /*增加任务*/ int destroy(); };
#include <stdio.h> #include <unistd.h> #include <string.h> #include <assert.h> #include "multi.h" worker_queue::worker_queue():head(NULL),tail(NULL),cur_size(0),destroy(false){ pthread_mutex_init(&mutex,NULL); pthread_cond_init(&ready,NULL); } worker_queue::~worker_queue(){ clean(); destroy = true ; pthread_cond_broadcast(&ready); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&ready); } int worker_queue::clean(){ worker_node* temp; pthread_mutex_lock(&mutex); while(NULL!=head){ temp = head ; head = head->next ; delete temp ; } tail=head=NULL; cur_size = 0; pthread_mutex_unlock(&mutex); return 0; } int worker_queue::in_queue(const worker_node *node){ worker_node *temp; temp = new worker_node ; if(NULL == temp) return -1 ; //new err ; *temp = *node ; pthread_mutex_lock(&mutex); if(NULL==head){ head=tail=temp; }else{ tail->next=temp ; tail = temp ; tail->next = NULL; } cur_size++; pthread_mutex_unlock(&mutex); pthread_cond_signal(&ready); return 0 ; } worker_node * worker_queue::out_queue(){ //out of the queue pthread_mutex_lock(&mutex); while((NULL==head) && (false == destroy)) { //queue empty pthread_cond_wait(&ready,&mutex); } // assert(head!=NULL); // assert(cur_size!=0); if(destroy){ pthread_mutex_unlock(&mutex); return NULL; } worker_node *temp; temp = head ; head = head->next ; cur_size -- ; pthread_mutex_unlock(&mutex); return temp; } pmulti::pmulti(): is_init(false),thread_num(0),w_queue(NULL),threads(NULL),is_destroy(false){ } pmulti::~pmulti(){ } int pmulti::init(unsigned int thr_num){ if(is_init) return -1;//alread init int i; //pool = new thread_pool; //if(NULL == pool) return -2;//new error //bzero(pool,sizeof(thread_pool)); w_queue = new worker_queue ; if(NULL == w_queue) return -2;//new error thread_num = thr_num; threads = new pthread_t[thr_num] ; for(i=0;i<thr_num;i++){ if(0!=pthread_create((threads+i),NULL,thread_fun,(void*)this )) printf("pthread_create error\n"); } is_destroy = false ; is_init = true; return 0; } int pmulti::add_worker(const worker_node * node){ return w_queue->in_queue(node); } int pmulti::destroy(){ int i=0; char* res; is_destroy = true ; if(NULL != w_queue) delete w_queue; for(i=0;i<thread_num;i++){ pthread_join(threads[i],(void**)&res); printf("joined :%lld end;\n",res); } if(thread_num > 0) delete[] threads; return 0; } void* pmulti::thread_fun(void*arg){ printf("thread num:%lld\n",pthread_self()); pmulti *pm =(pmulti*)arg; worker_node * node ; while(1){ if(pm->is_destroy) pthread_exit(NULL); node = pm->w_queue->out_queue(); if((NULL == node)|| (pm->is_destroy)) pthread_exit(NULL); node->process(node->arg); printf("thread_fun:%lld run\n",pthread_self()); } return (void*)pthread_self(); }
void * test(void* i){ printf("test:%d\n",( int)i); sleep(1); return NULL; } int main(int argc,char ** args){ printf("this is main!\n"); class pmulti pm; pm.init(15); worker_node no ; for(int i=0;i<5;i++){ no.process = &test ; no.arg = (void*)(i*2); pm.add_worker(&no); } sleep(5); pm.destroy(); return 0; }运行结果: