線程池的設計與測試

編寫了一個最基本的線程池類,處理用c_work表示的工作任務。C++還很不熟練,歡迎會C++的提出寶貴的修改意見。

程序有註釋,所以應該很好讀懂。測試程序在下面。




  1. ///////////////////////////////////////////////////////  
  2. //線程池類   
  3. ///////////////////////////////////////////////////////  
  4. #include <pthread.h>  
  5. #include <stdlib.h>  
  6. #include <stdio.h>  
  7. #include <unistd.h>  
  8. #include <assert.h>  
  9.   
  10. const int DEFAULT_MAX_THREAD_NUM = 10;  
  11. const int MAX_WORK_NUM = 100000;  
  12. //c_worker類  
  13. class c_work  
  14. {  
  15.     public:  
  16.         c_work():process(NULL), arg(NULL), next(NULL){}  
  17.         c_work(void *(*prcss)(void *), void *arg):  
  18.             process(prcss), arg(arg), next(NULL) {}  
  19.         ~c_work();   
  20.   
  21.         void *(*process)(void *);  
  22.         void *arg;  
  23.         unsigned char type; //最高位表示arg是否需要delete操作  
  24.         c_work *next;  
  25. };  
  26.   
  27. c_work::~c_work()  
  28. {  
  29.     unsigned char ifdel = type >> 7;  
  30.     if (ifdel)  
  31.     {  
  32.         delete arg;  
  33.         arg = NULL;  
  34.     }  
  35. }  
  36.   
  37. class c_thread_pool  
  38. {  
  39.     public:  
  40.         c_thread_pool();  
  41.         c_thread_pool(const int max_thread_num);  
  42.         ~c_thread_pool();  
  43.   
  44.         int add_work(c_work work);  
  45.         static void *thread_routine(void *arg);  
  46.   
  47.         pthread_mutex_t queue_lock;  
  48.         pthread_cond_t queue_cond;  
  49.   
  50. //  private:  
  51.         c_work *queue_head;  
  52.         c_work *queue_tail;  
  53.         int shutdown;  
  54.   
  55.         pthread_t *threadid;  
  56.         int max_thread_num;  
  57.         int cur_queue_size;  
  58. };  
  59.   
  60. c_thread_pool::c_thread_pool()  
  61. {  
  62.   
  63.     pthread_mutex_init(&queue_lock, NULL);  
  64.     pthread_cond_init(&queue_cond, NULL);  
  65.   
  66.     //工作隊列初始化  
  67.     queue_head = NULL;  
  68.     queue_tail = NULL;  
  69.       
  70.     max_thread_num = max_thread_num;  
  71.     cur_queue_size = 0;  
  72.   
  73.     shutdown = 0;  
  74.   
  75.     max_thread_num = DEFAULT_MAX_THREAD_NUM;  
  76.     threadid = new pthread_t[max_thread_num];  
  77.     int i = 0;  
  78.   
  79.     for (i = 0; i < max_thread_num; i++)  
  80.     {  
  81.         pthread_create(&(threadid[i]), NULL, thread_routine, (void*)this);  
  82.     }  
  83. }  
  84.   
  85.   
  86. c_thread_pool::c_thread_pool(int max_thread_num)  
  87. {  
  88.   
  89.     pthread_mutex_init(&queue_lock, NULL);  
  90.     pthread_cond_init(&queue_cond, NULL);  
  91.   
  92.     //工作隊列初始化  
  93.     queue_head = NULL;  
  94.     queue_tail = NULL;  
  95.       
  96.     max_thread_num = max_thread_num;  
  97.     cur_queue_size = 0;  
  98.   
  99.     threadid = new pthread_t[max_thread_num];  
  100.     int i = 0;  
  101.     for (i = 0; i < max_thread_num; i++)  
  102.     {  
  103.         pthread_create(&(threadid[i]), NULL, thread_routine, (void*)this);  
  104.     }  
  105. }  
  106.   
  107. /*向線程池中的任務隊列加入任務*/  
  108. int c_thread_pool::add_work(c_work work)  
  109. {  
  110.     c_work *newwork = new c_work;  
  111.     newwork->process = work.process;  
  112.     newwork->arg = work.arg;  
  113.     newwork->next = NULL;  
  114.   
  115.     pthread_mutex_lock(&queue_lock);  
  116.       
  117.     /*將任務加入到等待隊列中*/  
  118.     if (queue_head != NULL && queue_tail != NULL)  
  119.     {  
  120.         queue_tail->next = newwork;  
  121.         queue_tail = newwork;     
  122.     }  
  123.     else  
  124.     {  
  125.         //空隊列  
  126.         queue_head = newwork;  
  127.         queue_tail = newwork;  
  128.     }  
  129.   
  130.     cur_queue_size++;  
  131.     pthread_mutex_unlock(&queue_lock);  
  132.     /*等待隊列中有任務了,喚醒一個等待線程,注意如果所有線程都在忙碌,這句沒有任何作用*/  
  133.     pthread_cond_signal(&(queue_cond));   
  134.     printf("add work returned!\n");  
  135.     return 0;  
  136. }  
  137.   
  138.   
  139. void* c_thread_pool::thread_routine(void *arg)  
  140. {  
  141.     c_thread_pool *pool = (c_thread_pool *)arg;  
  142.     int i = 0;  
  143.     while (1)  
  144.     {  
  145.         pthread_mutex_lock(&(pool->queue_lock));  
  146.         //如果等待隊列爲0並且不銷燬線程池,則處於阻塞狀態; 注意  
  147.          // pthread_cond_wait是一個原子操作,等待前會解鎖,喚醒後會加鎖  
  148.   
  149.         //標註:注意這一如果任務隊列不爲空的話,while語句將被跳過,直接執行下面的調用。  
  150.         while (pool->cur_queue_size == 0 && pool->shutdown)  
  151.         {  
  152.             pthread_cond_wait(&(pool->queue_cond), &(pool->queue_lock));  
  153.         }  
  154.   
  155.   
  156.         //等待隊列長度減去1,並取出鏈表中的頭元素  
  157.         if (pool->cur_queue_size > 0 && pool->queue_head != NULL)  
  158.         {  
  159.             printf("IN THREAD ROUTINE size = %d && queue head is not NULL\n", pool->cur_queue_size);  
  160.             pool->cur_queue_size--;  
  161.             c_work *work = pool->queue_head;  
  162.             pool->queue_head = work->next;  
  163.             pthread_mutex_unlock(&(pool->queue_lock));  
  164.   
  165.             //調用回調函數,執行測試任務  
  166.             //////////////////////////////////////////  
  167.             (*(work->process))(work->arg);  
  168.             free(work);  
  169.             work = NULL;  
  170.         }  
  171.         else //不可達  
  172.         {  
  173.             pthread_mutex_unlock(&(pool->queue_lock));  
  174.         }  
  175.     }  
  176.       
  177. }  
  178.   
  179. c_thread_pool::~c_thread_pool()  
  180. {  
  181.     for (int i = 0; i < max_thread_num; ++i)   
  182.         pthread_cancel(threadid[i]);  
  183.     for (c_work *w_t = queue_head; w_t != NULL;)  
  184.     {  
  185.         c_work *temp = w_t->next;  
  186.         delete w_t;  
  187.         w_t = temp;  
  188.     }  
  189.     delete [] threadid;  
  190. }  



  1. ///////////////////////////////////////////////////////  
  2. //線程池類   
  3. ///////////////////////////////////////////////////////  
  4. #include <pthread.h>  
  5. #include <stdlib.h>  
  6. #include <stdio.h>  
  7. #include <unistd.h>  
  8. #include <assert.h>  
  9.   
  10. const int DEFAULT_MAX_THREAD_NUM = 10;  
  11. const int MAX_WORK_NUM = 100000;  
  12. //c_worker類  
  13. class c_work  
  14. {  
  15.     public:  
  16.         c_work():process(NULL), arg(NULL), next(NULL){}  
  17.         c_work(void *(*prcss)(void *), void *arg):  
  18.             process(prcss), arg(arg), next(NULL) {}  
  19.         ~c_work();   
  20.   
  21.         void *(*process)(void *);  
  22.         void *arg;  
  23.         unsigned char type; //最高位表示arg是否需要delete操作  
  24.         c_work *next;  
  25. };  
  26.   
  27. c_work::~c_work()  
  28. {  
  29.     unsigned char ifdel = type >> 7;  
  30.     if (ifdel)  
  31.     {  
  32.         delete arg;  
  33.         arg = NULL;  
  34.     }  
  35. }  
  36.   
  37. class c_thread_pool  
  38. {  
  39.     public:  
  40.         c_thread_pool();  
  41.         c_thread_pool(const int max_thread_num);  
  42.         ~c_thread_pool();  
  43.   
  44.         int add_work(c_work work);  
  45.         static void *thread_routine(void *arg);  
  46.   
  47.         pthread_mutex_t queue_lock;  
  48.         pthread_cond_t queue_cond;  
  49.   
  50. //  private:  
  51.         c_work *queue_head;  
  52.         c_work *queue_tail;  
  53.         int shutdown;  
  54.   
  55.         pthread_t *threadid;  
  56.         int max_thread_num;  
  57.         int cur_queue_size;  
  58. };  
  59.   
  60. c_thread_pool::c_thread_pool()  
  61. {  
  62.   
  63.     pthread_mutex_init(&queue_lock, NULL);  
  64.     pthread_cond_init(&queue_cond, NULL);  
  65.   
  66.     //工作隊列初始化  
  67.     queue_head = NULL;  
  68.     queue_tail = NULL;  
  69.       
  70.     max_thread_num = max_thread_num;  
  71.     cur_queue_size = 0;  
  72.   
  73.     shutdown = 0;  
  74.   
  75.     max_thread_num = DEFAULT_MAX_THREAD_NUM;  
  76.     threadid = new pthread_t[max_thread_num];  
  77.     int i = 0;  
  78.   
  79.     for (i = 0; i < max_thread_num; i++)  
  80.     {  
  81.         pthread_create(&(threadid[i]), NULL, thread_routine, (void*)this);  
  82.     }  
  83. }  
  84.   
  85.   
  86. c_thread_pool::c_thread_pool(int max_thread_num)  
  87. {  
  88.   
  89.     pthread_mutex_init(&queue_lock, NULL);  
  90.     pthread_cond_init(&queue_cond, NULL);  
  91.   
  92.     //工作隊列初始化  
  93.     queue_head = NULL;  
  94.     queue_tail = NULL;  
  95.       
  96.     max_thread_num = max_thread_num;  
  97.     cur_queue_size = 0;  
  98.   
  99.     threadid = new pthread_t[max_thread_num];  
  100.     int i = 0;  
  101.     for (i = 0; i < max_thread_num; i++)  
  102.     {  
  103.         pthread_create(&(threadid[i]), NULL, thread_routine, (void*)this);  
  104.     }  
  105. }  
  106.   
  107. /*向線程池中的任務隊列加入任務*/  
  108. int c_thread_pool::add_work(c_work work)  
  109. {  
  110.     c_work *newwork = new c_work;  
  111.     newwork->process = work.process;  
  112.     newwork->arg = work.arg;  
  113.     newwork->next = NULL;  
  114.   
  115.     pthread_mutex_lock(&queue_lock);  
  116.       
  117.     /*將任務加入到等待隊列中*/  
  118.     if (queue_head != NULL && queue_tail != NULL)  
  119.     {  
  120.         queue_tail->next = newwork;  
  121.         queue_tail = newwork;     
  122.     }  
  123.     else  
  124.     {  
  125.         //空隊列  
  126.         queue_head = newwork;  
  127.         queue_tail = newwork;  
  128.     }  
  129.   
  130.     cur_queue_size++;  
  131.     pthread_mutex_unlock(&queue_lock);  
  132.     /*等待隊列中有任務了,喚醒一個等待線程,注意如果所有線程都在忙碌,這句沒有任何作用*/  
  133.     pthread_cond_signal(&(queue_cond));   
  134.     printf("add work returned!\n");  
  135.     return 0;  
  136. }  
  137.   
  138.   
  139. void* c_thread_pool::thread_routine(void *arg)  
  140. {  
  141.     c_thread_pool *pool = (c_thread_pool *)arg;  
  142.     int i = 0;  
  143.     while (1)  
  144.     {  
  145.         pthread_mutex_lock(&(pool->queue_lock));  
  146.         //如果等待隊列爲0並且不銷燬線程池,則處於阻塞狀態; 注意  
  147.          // pthread_cond_wait是一個原子操作,等待前會解鎖,喚醒後會加鎖  
  148.   
  149.         //標註:注意這一如果任務隊列不爲空的話,while語句將被跳過,直接執行下面的調用。  
  150.         while (pool->cur_queue_size == 0 && pool->shutdown)  
  151.         {  
  152.             pthread_cond_wait(&(pool->queue_cond), &(pool->queue_lock));  
  153.         }  
  154.   
  155.   
  156.         //等待隊列長度減去1,並取出鏈表中的頭元素  
  157.         if (pool->cur_queue_size > 0 && pool->queue_head != NULL)  
  158.         {  
  159.             printf("IN THREAD ROUTINE size = %d && queue head is not NULL\n", pool->cur_queue_size);  
  160.             pool->cur_queue_size--;  
  161.             c_work *work = pool->queue_head;  
  162.             pool->queue_head = work->next;  
  163.             pthread_mutex_unlock(&(pool->queue_lock));  
  164.   
  165.             //調用回調函數,執行測試任務  
  166.             //////////////////////////////////////////  
  167.             (*(work->process))(work->arg);  
  168.             free(work);  
  169.             work = NULL;  
  170.         }  
  171.         else //不可達  
  172.         {  
  173.             pthread_mutex_unlock(&(pool->queue_lock));  
  174.         }  
  175.     }  
  176.       
  177. }  
  178.   
  179. c_thread_pool::~c_thread_pool()  
  180. {  
  181.     for (int i = 0; i < max_thread_num; ++i)   
  182.         pthread_cancel(threadid[i]);  
  183.     for (c_work *w_t = queue_head; w_t != NULL;)  
  184.     {  
  185.         c_work *temp = w_t->next;  
  186.         delete w_t;  
  187.         w_t = temp;  
  188.     }  
  189.     delete [] threadid;  
  190. }  

  1. #include "___pool.h"  
  2.   
  3. struct adder  
  4. {  
  5.     int a;  
  6.     int b;  
  7. };  
  8.   
  9. void *process(void *add)  
  10. {  
  11.     struct adder *addp = (struct adder*)add;  
  12.     printf("-----in process:\n");  
  13.     printf("sum = %d + %d = %d\n", addp->a, addp->b, addp->a +  addp->b);  
  14.     return (void *)0;  
  15. }  
  16. int main(int argc, char **argv)  
  17. {  
  18.     if (argc < 2)  
  19.     {     
  20.         printf("input task num!\n");  
  21.         return -1;  
  22.     }  
  23.     int num = atoi(argv[1]);  
  24.     int i;  
  25.     c_thread_pool pool(10);           
  26.     struct adder add[num];  
  27.     for (i = 0; i < num; i++)  
  28.     {  
  29.         add[i].a = i + 1;  
  30.         add[i].b = i + 1;  
  31.     }  
  32.     c_worker wker[num];  
  33.     for (i = 0; i < num; i++)  
  34.     {  
  35.         wker[i].process = process;  
  36.         wker[i].arg = &add[i];  
  37.     }  
  38.     for (i = 0; i < num; i++)  
  39.     {  
  40.         pool.add_worker(wker[i]);  
  41.     }  
  42.     sleep(100);  
  43.     printf("\n");  
  44.     return 0;  
  45. }  


原文地址:http://blog.csdn.net/naturebe/article/details/7901130

  1. ///////////////////////////////////////////////////////  
  2. //線程池類   
  3. ///////////////////////////////////////////////////////  
  4. #include <pthread.h>  
  5. #include <stdlib.h>  
  6. #include <stdio.h>  
  7. #include <unistd.h>  
  8. #include <assert.h>  
  9.   
  10. const int DEFAULT_MAX_THREAD_NUM = 10;  
  11. const int MAX_WORK_NUM = 100000;  
  12. //c_worker類  
  13. class c_work  
  14. {  
  15.     public:  
  16.         c_work():process(NULL), arg(NULL), next(NULL){}  
  17.         c_work(void *(*prcss)(void *), void *arg):  
  18.             process(prcss), arg(arg), next(NULL) {}  
  19.         ~c_work();   
  20.   
  21.         void *(*process)(void *);  
  22.         void *arg;  
  23.         unsigned char type; //最高位表示arg是否需要delete操作  
  24.         c_work *next;  
  25. };  
  26.   
  27. c_work::~c_work()  
  28. {  
  29.     unsigned char ifdel = type >> 7;  
  30.     if (ifdel)  
  31.     {  
  32.         delete arg;  
  33.         arg = NULL;  
  34.     }  
  35. }  
  36.   
  37. class c_thread_pool  
  38. {  
  39.     public:  
  40.         c_thread_pool();  
  41.         c_thread_pool(const int max_thread_num);  
  42.         ~c_thread_pool();  
  43.   
  44.         int add_work(c_work work);  
  45.         static void *thread_routine(void *arg);  
  46.   
  47.         pthread_mutex_t queue_lock;  
  48.         pthread_cond_t queue_cond;  
  49.   
  50. //  private:  
  51.         c_work *queue_head;  
  52.         c_work *queue_tail;  
  53.         int shutdown;  
  54.   
  55.         pthread_t *threadid;  
  56.         int max_thread_num;  
  57.         int cur_queue_size;  
  58. };  
  59.   
  60. c_thread_pool::c_thread_pool()  
  61. {  
  62.   
  63.     pthread_mutex_init(&queue_lock, NULL);  
  64.     pthread_cond_init(&queue_cond, NULL);  
  65.   
  66.     //工作隊列初始化  
  67.     queue_head = NULL;  
  68.     queue_tail = NULL;  
  69.       
  70.     max_thread_num = max_thread_num;  
  71.     cur_queue_size = 0;  
  72.   
  73.     shutdown = 0;  
  74.   
  75.     max_thread_num = DEFAULT_MAX_THREAD_NUM;  
  76.     threadid = new pthread_t[max_thread_num];  
  77.     int i = 0;  
  78.   
  79.     for (i = 0; i < max_thread_num; i++)  
  80.     {  
  81.         pthread_create(&(threadid[i]), NULL, thread_routine, (void*)this);  
  82.     }  
  83. }  
  84.   
  85.   
  86. c_thread_pool::c_thread_pool(int max_thread_num)  
  87. {  
  88.   
  89.     pthread_mutex_init(&queue_lock, NULL);  
  90.     pthread_cond_init(&queue_cond, NULL);  
  91.   
  92.     //工作隊列初始化  
  93.     queue_head = NULL;  
  94.     queue_tail = NULL;  
  95.       
  96.     max_thread_num = max_thread_num;  
  97.     cur_queue_size = 0;  
  98.   
  99.     threadid = new pthread_t[max_thread_num];  
  100.     int i = 0;  
  101.     for (i = 0; i < max_thread_num; i++)  
  102.     {  
  103.         pthread_create(&(threadid[i]), NULL, thread_routine, (void*)this);  
  104.     }  
  105. }  
  106.   
  107. /*向線程池中的任務隊列加入任務*/  
  108. int c_thread_pool::add_work(c_work work)  
  109. {  
  110.     c_work *newwork = new c_work;  
  111.     newwork->process = work.process;  
  112.     newwork->arg = work.arg;  
  113.     newwork->next = NULL;  
  114.   
  115.     pthread_mutex_lock(&queue_lock);  
  116.       
  117.     /*將任務加入到等待隊列中*/  
  118.     if (queue_head != NULL && queue_tail != NULL)  
  119.     {  
  120.         queue_tail->next = newwork;  
  121.         queue_tail = newwork;     
  122.     }  
  123.     else  
  124.     {  
  125.         //空隊列  
  126.         queue_head = newwork;  
  127.         queue_tail = newwork;  
  128.     }  
  129.   
  130.     cur_queue_size++;  
  131.     pthread_mutex_unlock(&queue_lock);  
  132.     /*等待隊列中有任務了,喚醒一個等待線程,注意如果所有線程都在忙碌,這句沒有任何作用*/  
  133.     pthread_cond_signal(&(queue_cond));   
  134.     printf("add work returned!\n");  
  135.     return 0;  
  136. }  
  137.   
  138.   
  139. void* c_thread_pool::thread_routine(void *arg)  
  140. {  
  141.     c_thread_pool *pool = (c_thread_pool *)arg;  
  142.     int i = 0;  
  143.     while (1)  
  144.     {  
  145.         pthread_mutex_lock(&(pool->queue_lock));  
  146.         //如果等待隊列爲0並且不銷燬線程池,則處於阻塞狀態; 注意  
  147.          // pthread_cond_wait是一個原子操作,等待前會解鎖,喚醒後會加鎖  
  148.   
  149.         //標註:注意這一如果任務隊列不爲空的話,while語句將被跳過,直接執行下面的調用。  
  150.         while (pool->cur_queue_size == 0 && pool->shutdown)  
  151.         {  
  152.             pthread_cond_wait(&(pool->queue_cond), &(pool->queue_lock));  
  153.         }  
  154.   
  155.   
  156.         //等待隊列長度減去1,並取出鏈表中的頭元素  
  157.         if (pool->cur_queue_size > 0 && pool->queue_head != NULL)  
  158.         {  
  159.             printf("IN THREAD ROUTINE size = %d && queue head is not NULL\n", pool->cur_queue_size);  
  160.             pool->cur_queue_size--;  
  161.             c_work *work = pool->queue_head;  
  162.             pool->queue_head = work->next;  
  163.             pthread_mutex_unlock(&(pool->queue_lock));  
  164.   
  165.             //調用回調函數,執行測試任務  
  166.             //////////////////////////////////////////  
  167.             (*(work->process))(work->arg);  
  168.             free(work);  
  169.             work = NULL;  
  170.         }  
  171.         else //不可達  
  172.         {  
  173.             pthread_mutex_unlock(&(pool->queue_lock));  
  174.         }  
  175.     }  
  176.       
  177. }  
  178.   
  179. c_thread_pool::~c_thread_pool()  
  180. {  
  181.     for (int i = 0; i < max_thread_num; ++i)   
  182.         pthread_cancel(threadid[i]);  
  183.     for (c_work *w_t = queue_head; w_t != NULL;)  
  184.     {  
  185.         c_work *temp = w_t->next;  
  186.         delete w_t;  
  187.         w_t = temp;  
  188.     }  
  189.     delete [] threadid;  
  190. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章