什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。
下面列出线程的一些重要的函数
- 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);
下面是用C++实现线程池源码:
在该源码中,有两个文件,一个头文件pmutil.h, 一个源文件pmulti.cpp文件
下面是 pmuti.h 文件
- #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();
- };
pmulti.cpp文件
- #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);
- if((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;
- }
g++ multi.cpp multi.h -lpthread -o multi
[test@localhost multi_thread]$ ./multi
this is main!
thread num:24531909488
test:0
thread num:3046583152
test:2
thread num:3036093296
test:4
thread num:3025603440
test:6
thread num:3015113584
test:8
thread num:3004623728
thread num:3067562864
thread num:2994133872
thread num:2983644016
thread num:2973154160
thread num:2962664304
thread num:2952174448
thread num:2941684592
thread num:2931194736
thread num:3078052720
thread_fun:24531909488 run
thread_fun:3046583152 run
thread_fun:3036093296 run
thread_fun:3025603440 run
thread_fun:3015113584 run
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
joined :0 end;
参考博客: http://hi.baidu.com/boahegcrmdghots/item/f3ca1a3c2d47fcc52e8ec2e1
转自csdn博客:
http://blog.csdn.net/rao_warrior/article/details/8607228