linux中的线程池

一、线程池

大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时间内必须处理数目巨大的连接请求,但是处理时间却是比较短的。在传统的多线程服务器模型中是这样实现的:一旦有个请求到达,就创建一个新的线程,由该线程执行任务,任务执行完毕之后,线程就退出。这就是"即时创建,即时销毁"的策略。尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数非常频繁,那么服务器就将处于一个不停的创建线程和销毁线程的状态。这笔开销是不可忽略的,尤其是线程执行的时间非常非常短的情况。

  线程池就是为了解决上述问题的,它的实现原理是这样的:在应用程序启动之后,就马上创建一定数量的线程,放入空闲的队列中。这些线程都是处于阻塞状态,这些线程只占一点内存,不占用CPU。当任务到来后,线程池将选择一个空闲的线程,将任务传入此线程中运行。当所有的线程都处在处理任务的时候,线程池将自动创建一定的数量的新线程,用于处理更多的任务。执行任务完成之后线程并不退出,而是继续在线程池中等待下一次任务。当大部分线程处于阻塞状态时,线程池将自动销毁一部分的线程,回收系统资源。

  下面是一个简单线程池的实现,这个线程池的代码是我参考网上的一个例子实现的,由于找不到出处了,就没办法注明参考自哪里了。它的方案是这样的:程序启动之前,初始化线程池,启动线程池中的线程,由于还没有任务到来,线程池中的所有线程都处在阻塞状态,当一有任务到达就从线程池中取出一个空闲线程处理,如果所有的线程都处于工作状态,就添加到队列,进行排队。如果队列中的任务个数大于队列的所能容纳的最大数量,那就不能添加任务到队列中,只能等待队列不满才能添加任务到队列中。

  主要由两个文件组成一个threadpool.h头文件和一个threadpool.c源文件组成。源码中已有重要的注释,就不加以分析了。

  threadpool.h文件:

  1. struct job  
  2. {  
  3.     void* (*callback_function)(void *arg);    //线程回调函数  
  4.     void *arg;                                //回调函数参数  
  5.     struct job *next;  
  6. };  
  7.   
  8. struct threadpool  
  9. {  
  10.     int thread_num;                   //线程池中开启线程的个数  
  11.     int queue_max_num;                //队列中最大job的个数  
  12.     struct job *head;                 //指向job的头指针  
  13.     struct job *tail;                 //指向job的尾指针  
  14.     pthread_t *pthreads;              //线程池中所有线程的pthread_t  
  15.     pthread_mutex_t mutex;            //互斥信号量  
  16.     pthread_cond_t queue_empty;       //队列为空的条件变量  
  17.     pthread_cond_t queue_not_empty;   //队列不为空的条件变量  
  18.     pthread_cond_t queue_not_full;    //队列不为满的条件变量  
  19.     int queue_cur_num;                //队列当前的job个数  
  20.     int queue_close;                  //队列是否已经关闭  
  21.     int pool_close;                   //线程池是否已经关闭  
  22. };  
  23.   
  24. //================================================================================================  
  25. //函数名:                   threadpool_init  
  26. //函数描述:                 初始化线程池  
  27. //输入:                    [in] thread_num     线程池开启的线程个数  
  28. //                         [in] queue_max_num  队列的最大job个数   
  29. //输出:                    无  
  30. //返回:                    成功:线程池地址 失败:NULL  
  31. //================================================================================================  
  32. struct threadpool* threadpool_init(int thread_num, int queue_max_num);  
  33.   
  34. //================================================================================================  
  35. //函数名:                    threadpool_add_job  
  36. //函数描述:                  向线程池中添加任务  
  37. //输入:                     [in] pool                  线程池地址  
  38. //                          [in] callback_function     回调函数  
  39. //                          [in] arg                     回调函数参数  
  40. //输出:                     无  
  41. //返回:                     成功:0 失败:-1  
  42. //================================================================================================  
  43. int threadpool_add_job(struct threadpool *pool, void* (*callback_function)(void *arg), void *arg);  
  44.   
  45. //================================================================================================  
  46. //函数名:                    threadpool_destroy  
  47. //函数描述:                   销毁线程池  
  48. //输入:                      [in] pool                  线程池地址  
  49. //输出:                      无  
  50. //返回:                      成功:0 失败:-1  
  51. //================================================================================================  
  52. int threadpool_destroy(struct threadpool *pool);  
  53.   
  54. //================================================================================================  
  55. //函数名:                    threadpool_function  
  56. //函数描述:                  线程池中线程函数  
  57. //输入:                     [in] arg                  线程池地址  
  58. //输出:                     无    
  59. //返回:                     无  
  60. //================================================================================================  
  61. void* threadpool_function(void* arg);  
 threadpool.c文件:

  1. #include "threadpool.h"  
  2.   
  3. struct threadpool* threadpool_init(int thread_num, int queue_max_num)  
  4. {  
  5.     struct threadpool *pool = NULL;  
  6.     do   
  7.     {  
  8.         pool = malloc(sizeof(struct threadpool));  
  9.         if (NULL == pool)  
  10.         {  
  11.             printf("failed to malloc threadpool!\n");  
  12.             break;  
  13.         }  
  14.         pool->thread_num = thread_num;  
  15.         pool->queue_max_num = queue_max_num;  
  16.         pool->queue_cur_num = 0;  
  17.         pool->head = NULL;  
  18.         pool->tail = NULL;  
  19.         if (pthread_mutex_init(&(pool->mutex), NULL))  
  20.         {  
  21.             printf("failed to init mutex!\n");  
  22.             break;  
  23.         }  
  24.         if (pthread_cond_init(&(pool->queue_empty), NULL))  
  25.         {  
  26.             printf("failed to init queue_empty!\n");  
  27.             break;  
  28.         }  
  29.         if (pthread_cond_init(&(pool->queue_not_empty), NULL))  
  30.         {  
  31.             printf("failed to init queue_not_empty!\n");  
  32.             break;  
  33.         }  
  34.         if (pthread_cond_init(&(pool->queue_not_full), NULL))  
  35.         {  
  36.             printf("failed to init queue_not_full!\n");  
  37.             break;  
  38.         }  
  39.         pool->pthreads = malloc(sizeof(pthread_t) * thread_num);  
  40.         if (NULL == pool->pthreads)  
  41.         {  
  42.             printf("failed to malloc pthreads!\n");  
  43.             break;  
  44.         }  
  45.         pool->queue_close = 0;  
  46.         pool->pool_close = 0;  
  47.         int i;  
  48.         for (i = 0; i < pool->thread_num; ++i)  
  49.         {  
  50.             pthread_create(&(pool->pthreads[i]), NULL, threadpool_function, (void *)pool);  
  51.         }  
  52.           
  53.         return pool;      
  54.     } while (0);  
  55.       
  56.     return NULL;  
  57. }  
  58.   
  59. int threadpool_add_job(struct threadpool* pool, void* (*callback_function)(void *arg), void *arg)  
  60. {  
  61.     assert(pool != NULL);  
  62.     assert(callback_function != NULL);  
  63.     assert(arg != NULL);  
  64.   
  65.     pthread_mutex_lock(&(pool->mutex));  
  66.     while ((pool->queue_cur_num == pool->queue_max_num) && !(pool->queue_close || pool->pool_close))  
  67.     {  
  68.         pthread_cond_wait(&(pool->queue_not_full), &(pool->mutex));   //队列满的时候就等待  
  69.     }  
  70.     if (pool->queue_close || pool->pool_close)    //队列关闭或者线程池关闭就退出  
  71.     {  
  72.         pthread_mutex_unlock(&(pool->mutex));  
  73.         return -1;  
  74.     }  
  75.     struct job *pjob =(struct job*) malloc(sizeof(struct job));  
  76.     if (NULL == pjob)  
  77.     {  
  78.         pthread_mutex_unlock(&(pool->mutex));  
  79.         return -1;  
  80.     }   
  81.     pjob->callback_function = callback_function;      
  82.     pjob->arg = arg;  
  83.     pjob->next = NULL;  
  84.     if (pool->head == NULL)     
  85.     {  
  86.         pool->head = pool->tail = pjob;  
  87.         pthread_cond_broadcast(&(pool->queue_not_empty));  //队列空的时候,有任务来时就通知线程池中的线程:队列非空  
  88.     }  
  89.     else  
  90.     {  
  91.         pool->tail->next = pjob;  
  92.         pool->tail = pjob;      
  93.     }  
  94.     pool->queue_cur_num++;  
  95.     pthread_mutex_unlock(&(pool->mutex));  
  96.     return 0;  
  97. }  
  98.   
  99. void* threadpool_function(void* arg)  
  100. {  
  101.     struct threadpool *pool = (struct threadpool*)arg;  
  102.     struct job *pjob = NULL;  
  103.     while (1)  //死循环  
  104.     {  
  105.         pthread_mutex_lock(&(pool->mutex));  
  106.         while ((pool->queue_cur_num == 0) && !pool->pool_close)   //队列为空时,就等待队列非空  
  107.         {  
  108.             pthread_cond_wait(&(pool->queue_not_empty), &(pool->mutex));  
  109.         }  
  110.         if (pool->pool_close)   //线程池关闭,线程就退出  
  111.         {  
  112.             pthread_mutex_unlock(&(pool->mutex));  
  113.             pthread_exit(NULL);  
  114.         }  
  115.         pool->queue_cur_num--;  
  116.         pjob = pool->head;  
  117.         if (pool->queue_cur_num == 0)  
  118.         {  
  119.             pool->head = pool->tail = NULL;  
  120.         }  
  121.         else   
  122.         {  
  123.             pool->head = pjob->next;  
  124.         }  
  125.         if (pool->queue_cur_num == 0)  
  126.         {  
  127.             pthread_cond_signal(&(pool->queue_empty));        //队列为空,就可以通知threadpool_destroy函数,销毁线程函数  
  128.         }  
  129.         if (pool->queue_cur_num == pool->queue_max_num - 1)  
  130.         {  
  131.             pthread_cond_broadcast(&(pool->queue_not_full));  //队列非满,就可以通知threadpool_add_job函数,添加新任务  
  132.         }  
  133.         pthread_mutex_unlock(&(pool->mutex));  
  134.           
  135.         (*(pjob->callback_function))(pjob->arg);   //线程真正要做的工作,回调函数的调用  
  136.         free(pjob);  
  137.         pjob = NULL;      
  138.     }  
  139. }  
  140. int threadpool_destroy(struct threadpool *pool)  
  141. {  
  142.     assert(pool != NULL);  
  143.     pthread_mutex_lock(&(pool->mutex));  
  144.     if (pool->queue_close || pool->pool_close)   //线程池已经退出了,就直接返回  
  145.     {  
  146.         pthread_mutex_unlock(&(pool->mutex));  
  147.         return -1;  
  148.     }  
  149.       
  150.     pool->queue_close = 1;        //置队列关闭标志  
  151.     while (pool->queue_cur_num != 0)  
  152.     {  
  153.         pthread_cond_wait(&(pool->queue_empty), &(pool->mutex));  //等待队列为空  
  154.     }      
  155.       
  156.     pool->pool_close = 1;      //置线程池关闭标志  
  157.     pthread_mutex_unlock(&(pool->mutex));  
  158.     pthread_cond_broadcast(&(pool->queue_not_empty));  //唤醒线程池中正在阻塞的线程  
  159.     pthread_cond_broadcast(&(pool->queue_not_full));   //唤醒添加任务的threadpool_add_job函数  
  160.     int i;  
  161.     for (i = 0; i < pool->thread_num; ++i)  
  162.     {  
  163.         pthread_join(pool->pthreads[i], NULL);    //等待线程池的所有线程执行完毕  
  164.     }  
  165.       
  166.     pthread_mutex_destroy(&(pool->mutex));          //清理资源  
  167.     pthread_cond_destroy(&(pool->queue_empty));  
  168.     pthread_cond_destroy(&(pool->queue_not_empty));     
  169.     pthread_cond_destroy(&(pool->queue_not_full));      
  170.     free(pool->pthreads);  
  171.     struct job *p;  
  172.     while (pool->head != NULL)  
  173.     {  
  174.         p = pool->head;  
  175.         pool->head = p->next;  
  176.         free(p);  
  177.     }  
  178.     free(pool);  
  179.     return 0;  
  180. }  
测试文件main.c文件:

  1. #include "threadpool.h"  
  2.   
  3. void* work(void* arg)  
  4. {  
  5.     char *p = (char*) arg;  
  6.     printf("threadpool callback fuction : %s.\n", p);  
  7.     sleep(1);  
  8. }  
  9.   
  10. int main(void)  
  11. {  
  12.     struct threadpool *pool = threadpool_init(10, 20);  
  13.     threadpool_add_job(pool, work, "1");  
  14.     threadpool_add_job(pool, work, "2");  
  15.     threadpool_add_job(pool, work, "3");  
  16.     threadpool_add_job(pool, work, "4");  
  17.     threadpool_add_job(pool, work, "5");  
  18.     threadpool_add_job(pool, work, "6");  
  19.     threadpool_add_job(pool, work, "7");  
  20.     threadpool_add_job(pool, work, "8");  
  21.     threadpool_add_job(pool, work, "9");  
  22.     threadpool_add_job(pool, work, "10");  
  23.     threadpool_add_job(pool, work, "11");  
  24.     threadpool_add_job(pool, work, "12");  
  25.     threadpool_add_job(pool, work, "13");  
  26.     threadpool_add_job(pool, work, "14");  
  27.     threadpool_add_job(pool, work, "15");  
  28.     threadpool_add_job(pool, work, "16");  
  29.     threadpool_add_job(pool, work, "17");  
  30.     threadpool_add_job(pool, work, "18");  
  31.     threadpool_add_job(pool, work, "19");  
  32.     threadpool_add_job(pool, work, "20");  
  33.     threadpool_add_job(pool, work, "21");  
  34.     threadpool_add_job(pool, work, "22");  
  35.     threadpool_add_job(pool, work, "23");  
  36.     threadpool_add_job(pool, work, "24");  
  37.     threadpool_add_job(pool, work, "25");  
  38.     threadpool_add_job(pool, work, "26");  
  39.     threadpool_add_job(pool, work, "27");  
  40.     threadpool_add_job(pool, work, "28");  
  41.     threadpool_add_job(pool, work, "29");  
  42.     threadpool_add_job(pool, work, "30");  
  43.     threadpool_add_job(pool, work, "31");  
  44.     threadpool_add_job(pool, work, "32");  
  45.     threadpool_add_job(pool, work, "33");  
  46.     threadpool_add_job(pool, work, "34");  
  47.     threadpool_add_job(pool, work, "35");  
  48.     threadpool_add_job(pool, work, "36");  
  49.     threadpool_add_job(pool, work, "37");  
  50.     threadpool_add_job(pool, work, "38");  
  51.     threadpool_add_job(pool, work, "39");  
  52.     threadpool_add_job(pool, work, "40");  
  53.   
  54.     sleep(5);  
  55.     threadpool_destroy(pool);  
  56.     return 0;  
  57. }  
二、线程池补充

上面的文章介绍了线程池的原理及意义。

下面,介绍的这个线程池与上面提到的那个线程池有一部分相似的地方。

  主要区别为:

    1、线程池中的每个线程都有自己的互斥量和条件变量,而不是线程池共享一个。

    2、线程池中的线程在程序结束时,等待线程池中线程停止的机制不同。

  该程序主要由两个文件构成,分别为ThreadPool.h和ThreadPool.cpp文件。

  ThreadPool.h文件:

  1. #define MAXT_IN_POOL 200  
  2. #define BUSY_THRESHOlD 0.5  
  3. #define MANAGE_INTREVAL 2  
  4.   
  5. class ThreadPool;  
  6.   
  7. typedef void (*dispatch_fn)(void*);      
  8.   
  9. //线程函数参数  
  10. typedef struct tagThread             
  11. {  
  12.     pthread_t thread_id;           //线程ID  
  13.     pthread_mutex_t thread_mutex;  //信号量  
  14.     pthread_cond_t thread_cond;    //条件变量  
  15.     dispatch_fn do_job;            //调用的函数,任务  
  16.     void* args;                    //函数参数  
  17.     ThreadPool *parent;            //线程池指针  
  18. }_thread;  
  19.   
  20. //线程池  
  21. class ThreadPool  
  22. {      
  23. public:  
  24.     //================================================================================================  
  25.     //函数名:                  ThreadPool  
  26.     //函数描述:                构造函数  
  27.     //输入:                    [in] max_threads_in_pool 线程池最大线程数  
  28.     //输入:                    [in] min_threads_in_pool 线程池最小问题数  
  29.     //输出:                    无  
  30.     //返回:                    无  
  31.     //================================================================================================  
  32.     ThreadPool(unsigned int max_threads_in_pool, unsigned int min_threads_in_pool = 2);  
  33.     ~ThreadPool();  
  34.       
  35.     //================================================================================================  
  36.     //函数名:                  dispatch_threadpool  
  37.     //函数描述:                将任务加入线程池,由线程池进行分发  
  38.     //输入:                    [in] dispatch_me 调用的函数地址  
  39.     //输入:                    [in] dispatch_me 函数参数  
  40.     //输出:                    无  
  41.     //返回:                    无  
  42.     //================================================================================================  
  43.     void dispatch_threadpool(dispatch_fn dispatch_me, void* dispatch_me);  
  44. private:  
  45.     pthread_mutex_t tp_mutex;  //信号量  
  46.     pthread_cond_t tp_idle;    //线程池中线程有空闲线程的条件变量  
  47.     pthread_cond_t tp_full;    //线程池中线程为满的条件变量   
  48.     pthread_cond_t tp_empty;   //线程池中线程为空的条件变量  
  49.     int tp_min;                //线程池的最小线程数  
  50.     int tp_max;                //线程池的最大线程数  
  51.     int tp_avail;              //线程池中空闲的线程数  
  52.     int tp_total;              //线程池中已创建的线程数  
  53.     _thread** tp_list;         //指向线程池中所有空闲线程的参数的指针  
  54.     bool tp_stop;              //线程池是否已停止  
  55.       
  56.     //================================================================================================  
  57.     //函数名:                  add_avail  
  58.     //函数描述:                加入空闲线程  
  59.     //输入:                    [in] avail 线程的参数  
  60.     //输出:                    无  
  61.     //返回:                    成功:true,失败:false  
  62.     //================================================================================================  
  63.     bool add_avail(_thread* avail);  
  64.       
  65.     //================================================================================================  
  66.     //函数名:                  work_thread  
  67.     //函数描述:                线程函数  
  68.     //输入:                    [in] args 参数  
  69.     //输出:                    无  
  70.     //返回:                    无  
  71.     //================================================================================================  
  72.     static void* work_thread(void* args);  
  73.       
  74.     //================================================================================================  
  75.     //函数名:                  add_thread  
  76.     //函数描述:                添加一个线程  
  77.     //输入:                    [in] dispatch_me 函数指针  
  78.     //输入:                    [in] args        函数参数  
  79.     //输出:                    无  
  80.     //返回:                    无  
  81.     //================================================================================================  
  82.     bool add_thread(dispatch_fn dispatch_me, void* args);  
  83.       
  84.     //================================================================================================  
  85.     //函数名:                  syn_all  
  86.     //函数描述:                等待线程池中所有线程空闲  
  87.     //输入:                    无  
  88.     //输出:                    无  
  89.     //返回:                    无  
  90.     //================================================================================================  
  91.     void syn_all();      
  92. };  
ThreadPool.cpp文件:

  1. ThreadPool::ThreadPool(unsigned int max_threads_in_pool, unsigned int min_threads_in_pool)  
  2. {  
  3.     pthread_t manage_id;  
  4.   
  5.     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)  
  6.     {  
  7.         return ;  
  8.     }  
  9.   
  10.     tp_avail = 0;      //初始化线程池  
  11.     tp_total = 0;  
  12.     tp_min = min_threads_in_pool;  
  13.     tp_max = max_threads_in_pool;  
  14.     tp_stop = false;  
  15.     tp_list = (_thread * *)    malloc(sizeof(void *) * max_threads_in_pool);      
  16.     if (NULL == tp_list)  
  17.     {  
  18.         return;  
  19.     }  
  20.     memset(tp_list, 0, sizeof(void *) * max_threads_in_pool);  
  21.       
  22.     pthread_mutex_init(&tp_mutex, NULL);  
  23.     pthread_cond_init(&tp_idle, NULL);  
  24.     pthread_cond_init(&tp_full, NULL);  
  25.     pthread_cond_init(&tp_empty, NULL);  
  26. }  
  27.   
  28. bool ThreadPool::add_avail(_thread* avail)  
  29. {  
  30.     bool ret = false;  
  31.   
  32.     pthread_mutex_lock(&tp_mutex);  
  33.     if (tp_avail < tp_max)  
  34.     {  
  35.         tp_list[tp_avail] = avail;  
  36.         tp_avail++;          
  37.         pthread_cond_signal(&tp_idle);  //线程池中有线程为空闲  
  38.         if (tp_avail >= tp_total)  
  39.         {  
  40.             pthread_cond_signal(&tp_full); //线程池中所有线程都为为空闲  
  41.         }  
  42.         ret = true;  
  43.     }  
  44.     pthread_mutex_unlock(&tp_mutex);  
  45.       
  46.     return ret;  
  47. }  
  48.   
  49. void* ThreadPool::work_thread(void* args)  
  50. {  
  51.     _thread* thread = (_thread*) args;  
  52.     ThreadPool *pool = thread->parent;  
  53.     while (pool->tp_stop == false)   
  54.     {  
  55.         thread->do_job(thread->args);  
  56.         pthread_mutex_lock(&thread->thread_mutex); //执行完任务之后,添加到空闲线程队列中  
  57.         if (pool->add_avail(thread))  
  58.         {      
  59.             pthread_cond_wait(&thread->thread_cond, &thread->thread_mutex);  
  60.             pthread_mutex_unlock(&thread->thread_mutex);  
  61.         }  
  62.         else  
  63.         {  
  64.             pthread_mutex_unlock(&thread->thread_mutex);  
  65.             pthread_mutex_destroy(&thread->thread_mutex);  
  66.             pthread_cond_destroy(&thread->thread_cond);  
  67.             free(thread);  
  68.             break;  
  69.         }  
  70.     }  
  71.   
  72.     pthread_mutex_lock(&pool->tp_mutex);  
  73.     pool->tp_total--;  
  74.     if (pool->tp_total <= 0)  
  75.     {  
  76.         pthread_cond_signal(&pool->tp_empty);  
  77.     }  
  78.     pthread_mutex_unlock(&pool->tp_mutex);  
  79.   
  80.     return NULL;  
  81. }  
  82.   
  83. bool ThreadPool::add_thread(dispatch_fn dispatch_me, void* args)  //添加一个线程  
  84. {  
  85.     _thread* thread = NULL;  
  86.     pthread_attr_t attr;  
  87.       
  88.     thread = (_thread *) malloc(sizeof(_thread));  
  89.     if (NULL == thread)  
  90.     {  
  91.         return false;  
  92.     }  
  93.   
  94.     pthread_mutex_init(&thread->thread_mutex, NULL);  
  95.     pthread_cond_init(&thread->thread_cond, NULL);  
  96.     thread->do_job = dispatch_me;  
  97.     thread->args = args;  
  98.     thread->parent = this;  
  99.     pthread_attr_init(&attr);  
  100.     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);  
  101.   
  102.     if (pthread_create(&thread->thread_id, &attr, work_thread, (void *) thread) != 0)  
  103.     {  
  104.         pthread_mutex_destroy(&thread->thread_mutex);  
  105.         pthread_cond_destroy(&thread->thread_cond);  
  106.         pthread_attr_destroy(&attr);  
  107.         free(thread);  
  108.         return false;  
  109.     }                  
  110.     tp_total++;  
  111.   
  112.     return true;  
  113. }  
  114.   
  115. void ThreadPool::dispatch_threadpool(dispatch_fn dispatch_me, void* args)  
  116. {  
  117.     _thread* thread = NULL;  
  118.   
  119.     pthread_mutex_lock(&tp_mutex);  
  120.       
  121.     if (tp_avail <= 0 && tp_total >= tp_max) //无可用线程,而且线程数已达最大值,等待空闲线程  
  122.     {  
  123.         pthread_cond_wait(&tp_idle, &tp_mutex);  
  124.     }  
  125.   
  126.     if (tp_avail <= 0)  //无可用线程,而且线程数未达最大值,添加线程  
  127.     {  
  128.         if (!add_thread(dispatch_me, args))  
  129.         {  
  130.             return;  
  131.         }  
  132.     }  
  133.     else   //有可用线程  
  134.     {  
  135.         tp_avail--;  
  136.         thread = tp_list[tp_avail];  
  137.         tp_list[tp_avail] = NULL;          
  138.         thread->do_job = dispatch_me;  
  139.         thread->args = args;  
  140.   
  141.         pthread_mutex_lock(&thread->thread_mutex);  
  142.         pthread_cond_signal(&thread->thread_cond);  
  143.         pthread_mutex_unlock(&thread->thread_mutex);  
  144.     }  
  145.   
  146.     pthread_mutex_unlock(&tp_mutex);  
  147. }  
  148.   
  149.   
  150. void ThreadPool::syn_all()  
  151. {      
  152.     if (tp_avail < tp_total)   //等待线程池中所有线程都为空闲状态  
  153.     {  
  154.         pthread_cond_wait(&tp_full, &tp_mutex);  
  155.     }      
  156.       
  157.     tp_stop = true;      
  158.     int i = 0;      
  159.     for (i = 0; i < tp_avail; i++)  //唤醒线程池中所有线程  
  160.     {  
  161.         _thread *thread = tp_list[i];          
  162.         pthread_mutex_lock(&thread->thread_mutex);  
  163.         pthread_cond_signal(&thread->thread_cond);  
  164.         pthread_mutex_unlock(&thread->thread_mutex);  
  165.     }      
  166.     if (tp_total > 0)  
  167.     {  
  168.         pthread_cond_wait(&tp_empty, &tp_mutex);  //等待线程池中所有线程都结束  
  169.     }  
  170. }  
  171.   
  172. ThreadPool::~ThreadPool()  
  173. {  
  174.     sleep(MANAGE_INTREVAL);  
  175.     pthread_mutex_lock(&tp_mutex);  
  176.     syn_all();                        //等待线程池为空  
  177.     int i = 0;  
  178.     for (i = 0; i < tp_total; i++)  //资源释放  
  179.     {  
  180.         free(tp_list[i]);  
  181.         tp_list[i] = NULL;  
  182.     }  
  183.     pthread_mutex_unlock(&tp_mutex);  
  184.     pthread_mutex_destroy(&tp_mutex);  
  185.     pthread_cond_destroy(&tp_idle);  
  186.     pthread_cond_destroy(&tp_full);  
  187.     pthread_cond_destroy(&tp_empty);  
  188.     free(tp_list);  

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值