Linux C++ 實現線程池

http://blog.csdn.net/qq_25425023/article/details/53914609

線程池中的線程,在任務隊列為空的時候,等待任務的到來,任務隊列中有任務時,則依次獲取任務來執行,任務隊列需要同步。

? Linux線程同步有多種方法:互斥量、信號量、條件變量等。


? 下面是根據互斥量、信號量、條件變量封裝的三個類。

? 線程池中用到了互斥量和信號量。

?

[cpp]?view plain?copy
  1. #ifndef?_LOCKER_H_??
  2. #define?_LOCKER_H_??
  3. ??
  4. #include?<pthread.h>??
  5. #include?<stdio.h>??
  6. #include?<semaphore.h>??
  7. ??
  8. /*信號量的類*/??
  9. class?sem_locker??
  10. {??
  11. private:??
  12. ????sem_t?m_sem;??
  13. ??
  14. public:??
  15. ????//初始化信號量??
  16. ????sem_locker()??
  17. ????{??
  18. ????if(sem_init(&m_sem,?0,?0)?!=?0)??
  19. ????????printf("sem?init?error\n");??
  20. ????}??
  21. ????//銷毀信號量??
  22. ????~sem_locker()??
  23. ????{??
  24. ????sem_destroy(&m_sem);??
  25. ????}??
  26. ??
  27. ????//等待信號量??
  28. ????bool?wait()??
  29. ????{??
  30. ????return?sem_wait(&m_sem)?==?0;??
  31. ????}??
  32. ????//添加信號量??
  33. ????bool?add()??
  34. ????{??
  35. ????return?sem_post(&m_sem)?==?0;??
  36. ????}??
  37. };??
  38. ??
  39. ??
  40. /*互斥?locker*/??
  41. class?mutex_locker??
  42. {??
  43. private:??
  44. ????pthread_mutex_t?m_mutex;??
  45. ??
  46. public:??
  47. ????mutex_locker()??
  48. ????{??
  49. ????????if(pthread_mutex_init(&m_mutex,?NULL)?!=?0)??
  50. ????????printf("mutex?init?error!");??
  51. ????}??
  52. ????~mutex_locker()??
  53. ????{??
  54. ????pthread_mutex_destroy(&m_mutex);??
  55. ????}??
  56. ??
  57. ????bool?mutex_lock()??//lock?mutex??
  58. ????{??
  59. ????return?pthread_mutex_lock(&m_mutex)?==?0;??
  60. ????}??
  61. ????bool?mutex_unlock()???//unlock??
  62. ????{??
  63. ????return?pthread_mutex_unlock(&m_mutex)?==?0;??
  64. ????}??
  65. };??
  66. ??
  67. /*條件變量?locker*/??
  68. class?cond_locker??
  69. {??
  70. private:??
  71. ????pthread_mutex_t?m_mutex;??
  72. ????pthread_cond_t?m_cond;??
  73. ??
  74. public:??
  75. ????//?初始化?m_mutex?and?m_cond??
  76. ????cond_locker()??
  77. ????{??
  78. ????if(pthread_mutex_init(&m_mutex,?NULL)?!=?0)??
  79. ????????printf("mutex?init?error");??
  80. ????if(pthread_cond_init(&m_cond,?NULL)?!=?0)??
  81. ????{???//條件變量初始化是被,釋放初始化成功的mutex??
  82. ????????pthread_mutex_destroy(&m_mutex);??
  83. ????????printf("cond?init?error");??
  84. ????}??
  85. ????}??
  86. ????//?destroy?mutex?and?cond??
  87. ????~cond_locker()??
  88. ????{??
  89. ????pthread_mutex_destroy(&m_mutex);??
  90. ????pthread_cond_destroy(&m_cond);??
  91. ????}??
  92. ????//等待條件變量??
  93. ????bool?wait()??
  94. ????{??
  95. ????int?ans?=?0;??
  96. ????pthread_mutex_lock(&m_mutex);??
  97. ????ans?=?pthread_cond_wait(&m_cond,?&m_mutex);??
  98. ????pthread_mutex_unlock(&m_mutex);??
  99. ????return?ans?==?0;??
  100. ????}??
  101. ????//喚醒等待條件變量的線程??
  102. ????bool?signal()??
  103. ????{??
  104. ????return?pthread_cond_signal(&m_cond)?==?0;??
  105. ????}??
  106. ??
  107. };??
  108. ??
  109. #endif??

下面的是線程池類,是一個模版類:

[cpp]?view plain?copy
  1. #ifndef?_PTHREAD_POOL_??
  2. #define?_PTHREAD_POOL_??
  3. ??
  4. #include?"locker.h"??
  5. #include?<list>??
  6. #include?<stdio.h>??
  7. #include?<exception>??
  8. #include?<errno.h>??
  9. #include?<pthread.h>??
  10. #include?<iostream>??
  11. ??
  12. template<class?T>??
  13. class?threadpool??
  14. {??
  15. private:??
  16. ????int?thread_number;??//線程池的線程數??
  17. ????int?max_task_number;??//任務隊列中的最大任務數??
  18. ????pthread_t?*all_threads;???//線程數組??
  19. ????std::list<T?*>?task_queue;?//任務隊列??
  20. ????mutex_locker?queue_mutex_locker;??//互斥鎖??
  21. ????sem_locker?queue_sem_locker;???//信號量??
  22. ????bool?is_stop;?//是否結束線程??
  23. public:??
  24. ????threadpool(int?thread_num?=?20,?int?max_task_num?=?30);??
  25. ????~threadpool();??
  26. ????bool?append_task(T?*task);??
  27. ????void?start();??
  28. ????void?stop();??
  29. private:??
  30. ????//線程運行的函數。執行run()函數??
  31. ????static?void?*worker(void?*arg);??
  32. ????void?run();??
  33. };??
  34. ??
  35. template?<class?T>??
  36. threadpool<T>::threadpool(int?thread_num,?int?max_task_num):??
  37. ????thread_number(thread_num),?max_task_number(max_task_num),??
  38. ????is_stop(false),?all_threads(NULL)??
  39. {??
  40. ????if((thread_num?<=?0)?||?max_task_num?<=?0)??
  41. ????printf("threadpool?can't?init?because?thread_number?=?0"??
  42. ????????"?or?max_task_number?=?0");??
  43. ??
  44. ????all_threads?=?new?pthread_t[thread_number];??
  45. ????if(!all_threads)??
  46. ????????printf("can't?init?threadpool?because?thread?array?can't?new");??
  47. }??
  48. ??
  49. template?<class?T>??
  50. threadpool<T>::~threadpool()??
  51. {??
  52. ????delete?[]all_threads;??
  53. ????is_stop?=?true;??
  54. }??
  55. ??
  56. template?<class?T>??
  57. void?threadpool<T>::stop()??
  58. {??
  59. ????is_stop?=?true;??
  60. ????//queue_sem_locker.add();??
  61. }??
  62. ??
  63. template?<class?T>??
  64. void?threadpool<T>::start()??
  65. {??
  66. ????for(int?i?=?0;?i?<?thread_number;?++i)??
  67. ????{??
  68. ????printf("create?the?%dth?pthread\n",?i);??
  69. ????if(pthread_create(all_threads?+?i,?NULL,?worker,?this)?!=?0)??
  70. ????{//創建線程失敗,清除成功申請的資源并拋出異常??
  71. ????????delete?[]all_threads;??
  72. ????????throw?std::exception();??
  73. ????}??
  74. ????if(pthread_detach(all_threads[i]))??
  75. ????{//將線程設置為脫離線程,失敗則清除成功申請的資源并拋出異常??
  76. ????????delete?[]all_threads;??
  77. ????????throw?std::exception();??
  78. ????}??
  79. ????}??
  80. }??
  81. //添加任務進入任務隊列??
  82. template?<class?T>??
  83. bool?threadpool<T>::append_task(T?*task)??
  84. {???//獲取互斥鎖??
  85. ????queue_mutex_locker.mutex_lock();??
  86. ????//判斷隊列中任務數是否大于最大任務數??
  87. ????if(task_queue.size()?>?max_task_number)??
  88. ????{//是則釋放互斥鎖??
  89. ????queue_mutex_locker.mutex_unlock();??
  90. ????return?false;??
  91. ????}??
  92. ????//添加進入隊列??
  93. ????task_queue.push_back(task);??
  94. ????queue_mutex_locker.mutex_unlock();??
  95. ????//喚醒等待任務的線程??
  96. ????queue_sem_locker.add();??
  97. ????return?true;??
  98. }??
  99. ??
  100. template?<class?T>??
  101. void?*threadpool<T>::worker(void?*arg)??
  102. {??
  103. ????threadpool?*pool?=?(threadpool?*)arg;??
  104. ????pool->run();??
  105. ????return?pool;??
  106. }??
  107. ??
  108. template?<class?T>??
  109. void?threadpool<T>::run()??
  110. {??
  111. ????while(!is_stop)??
  112. ????{???//等待任務??
  113. ????queue_sem_locker.wait();??????
  114. ????if(errno?==?EINTR)??
  115. ????{??
  116. ????????printf("errno");??
  117. ????????continue;??
  118. ????}??
  119. ????//獲取互斥鎖??
  120. ????queue_mutex_locker.mutex_lock();??
  121. ????//判斷任務隊列是否為空??
  122. ????if(task_queue.empty())??
  123. ????{??
  124. ????????queue_mutex_locker.mutex_unlock();??
  125. ????????continue;??
  126. ????}??
  127. ????//獲取隊頭任務并執行??
  128. ????T?*task?=?task_queue.front();??
  129. ????task_queue.pop_front();??
  130. ????queue_mutex_locker.mutex_unlock();??
  131. ????if(!task)??
  132. ????????continue;??
  133. //??printf("pthreadId?=?%ld\n",?(unsigned?long)pthread_self());???
  134. ????task->doit();??//doit是T對象中的方法??
  135. ????}??
  136. ????//測試用??
  137. ????printf("close?%ld\n",?(unsigned?long)pthread_self());??
  138. }??
  139. ??
  140. #endif??

以上參考《Linux高性能服務器編程》


寫個程序對線程池進行測試:

[cpp]?view plain?copy
  1. #include?<stdio.h>??
  2. #include?<iostream>??
  3. #include?<unistd.h>??
  4. ??
  5. #include?"thread_pool.h"??
  6. ??
  7. class?task??
  8. {??
  9. private:??
  10. ????int?number;??
  11. ??
  12. public:??
  13. ????task(int?num)?:?number(num)??
  14. ????{??
  15. ????}??
  16. ????~task()??
  17. ????{??
  18. ????}??
  19. ??
  20. ????void?doit()??
  21. ????{??
  22. ????printf("this?is?the?%dth?task\n",?number);??
  23. ????}??
  24. };??
  25. ??
  26. int?main()??
  27. {??
  28. ????task?*ta;??
  29. ????threadpool<task>?pool(10,?15);??
  30. //????pool.start();??
  31. ????for(int?i?=?0;?i?<?20;?++i)??
  32. ????{??
  33. ????ta?=?new?task(i);??
  34. //??sleep(2);??
  35. ????pool.append_task(ta);??
  36. ????}??
  37. ????pool.start();??
  38. ????sleep(10);??
  39. ????printf("close?the?thread?pool\n");??
  40. ????pool.stop();??
  41. ????pause();??
  42. ????return?0;??
  43. }??

經測試,線程池可以正常使用。

下一篇博客,使用線程池來實現回射服務器,測試可以達到多大的并發量。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383817.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383817.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383817.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++制表符

制表符的轉義字符為\t&#xff0c;一般情況下長度為8個空格&#xff0c;這里的8個指的是從上一個字符串的開頭開始算&#xff0c;往后數8個&#xff0c;不夠的話就補空格。 如果前面的字符串的長度大于等于8個&#xff0c;例如前面字符串的長度為x,那么就會補(8-x%8)個空格 例…

C++派生類含有成員對象構造函數析構函數順序

參考博客&#xff1a;傳送門1 當類中含有對象成員時&#xff1a; 類的構造函數要包含對成員對象的初始化&#xff0c;如果構造函數的成員初始化列表沒有包含對成員對象的初始化&#xff0c;系統會自動調用成員對象的無參構造函數。順序上&#xff1a;先調用成員對象的構造函數…

c,c++中字符串處理函數strtok,strstr,strchr,strsub

http://blog.csdn.net/wangqing_12345/article/details/51760220 1&#xff0c;字符串切割函數 函數原型&#xff1a;char *strtok(char *s, char *delim); 函數功能&#xff1a;把字符串s按照字符串delim進行分割&#xff0c;然后返回分割的結果。 函數使用說&#xff1a; 1…

C++虛基類成員可見性

詳見《CPrimer》[第五版]719頁 如果繼承路徑上沒有和虛基類成員重名的成員&#xff0c;則不存在二義性&#xff0c;因為我們僅能訪問到虛基類成員。 當訪問僅有一條繼承路徑上含有和虛基類成員重名的成員&#xff0c;也不存在二義性。派生類的成員的優先級比基類的成員高&…

鏈表逆序的原理及實例

http://blog.csdn.net/wangqing_12345/article/details/51757294 尾插法建立鏈表&#xff0c;帶頭結點設鏈表節點為typedef struct node {int data;struct node *next;}node_t, *pnode_t;要求將一帶鏈表頭List head的單向鏈表逆序。 分析&#xff1a; 1). 若鏈表為空或只有一個…

C++關于虛基類、構造函數、析構函數、成員對象的兩個程序淺析

預備博客&#xff1a; C虛繼承中構造函數和析構函數順序問題以及原理 C派生類含有成員對象構造函數析構函數順序 C虛基類成員可見性 程序一如下&#xff1a; #include<iostream> using namespace std; class A { public:A(int a) :x(a) { cout << "A const…

strtok函數及其實現

頭文件&#xff1a;#include <string.h> 定義函數&#xff1a;char * strtok(char *s, const char *delim); 函數說明&#xff1a;strtok()用來將字符串分割成一個個片段。參數s 指向欲分割的字符串&#xff0c;參數delim 則為分割字符串&#xff0c;當 strtok()在參數s …

C++小型公司管理系統

項目要求&#xff1a; 編寫一個程序實現小型公司的人員信息管理系統。該公司雇員&#xff08;employee&#xff09;包括經理&#xff08;manager&#xff09;&#xff0c;技術人員&#xff08;technician&#xff09;、銷售員&#xff08;salesman&#xff09;和銷售部經理&…

Linux網絡編程“驚群”問題總結

http://www.cnblogs.com/Anker/p/7071849.html 1、前言 我從事Linux系統下網絡開發將近4年了&#xff0c;經常還是遇到一些問題&#xff0c;只是知其然而不知其所以然&#xff0c;有時候和其他人交流&#xff0c;搞得非常尷尬。如今計算機都是多核了&#xff0c;網絡編程框架也…

【Java學習筆記六】常用數據對象之String

字符串 在Java中系統定義了兩種類型的字符串類&#xff1a;String和StringBuffer String類對象的值和長度都不能改變&#xff0c;稱為常量字符串類&#xff0c;其中每個值稱為常量字符串。 StringBuffer類對象的值和長度都可以改變&#xff0c;稱為變量字符串類&#xff0c;其…

【Java學習筆記七】常用數據對象之數組

同一般的對象創建和定義一樣&#xff0c;數組的定義和創建可以分開進行也可以合并一起進行。 一維數組定義格式&#xff1a; <元素類型>[] <數組名>;//[]也可以放在數組名的后面一維數組創建格式&#xff1a; new <元素類型>[<元素個數>];執行new運…

yfan.qiu linux硬鏈接與軟鏈接

http://www.cnblogs.com/yfanqiu/archive/2012/06/11/2545556.html Linux 系統中有軟鏈接和硬鏈接兩種特殊的“文件”。 軟鏈接可以看作是Windows中的快捷方式&#xff0c;可以讓你快速鏈接到目標檔案或目錄。 硬鏈接則透過文件系統的inode來產生新檔名&#xff0c;而不是產生…

【Java學習筆記八】包裝類和vector

包裝類 在Java語言中&#xff0c;每一種基本的數據類型都有相應的對象類型&#xff0c;稱為他們基本類型的包裝類&#xff08;包裹類&#xff09;。 字節byte&#xff1a;Byte、短整數型short&#xff1a;Short 標準整數型int&#xff1a;Integer、長整數型long&#xff1a;Lo…

Linux C++線程池實例

http://www.cnblogs.com/danxi/p/6636095.html 想做一個多線程服務器測試程序&#xff0c;因此參考了github的一些實例&#xff0c;然后自己動手寫了類似的代碼來加深理解。 目前了解的線程池實現有2種思路&#xff1a; 第一種&#xff1a; 主進程創建一定數量的線程&#xff0…

Java編寫簡單的自定義異常類

除了系統中自己帶的異常&#xff0c;我們也可以自己寫一些簡單的異常類來幫助我們處理問題。 所有的異常命名都是以Exception結尾&#xff0c;并且都是Exception的子類。 假設我們要編寫一個人類的類&#xff0c;為了判斷年齡的輸入是否合法&#xff0c;我們編寫了一個名為Il…

shared_ptr簡介以及常見問題

http://blog.csdn.net/stelalala/article/details/19993425 本文中的shared_ptr以vs2010中的std::tr1::shared_ptr作為研究對象。可能和boost中的有些許差異&#xff0c;特此說明。 基本功能 shared_ptr提供了一個管理內存的簡單有效的方法。shared_ptr能在以下方面給開發提供便…

【Java學習筆記九】多線程

程序&#xff1a;計算機指令的集合&#xff0c;它以文件的形式存儲在磁盤上&#xff0c;是應用程序執行的藍本。 進程&#xff1a;是一個程序在其自身的地址空間中的一次執行活動。進程是資源申請、調度和獨立運行的單位&#xff0c;因此&#xff0c;它使用系統中的運行資源。而…

【C++11新特性】 C++11智能指針之weak_ptr

http://blog.csdn.net/xiejingfa/article/details/50772571 原創作品&#xff0c;轉載請標明&#xff1a;http://blog.csdn.net/Xiejingfa/article/details/50772571 如題&#xff0c;我們今天要講的是C11引入的三種智能指針中的最后一個&#xff1a;weak_ptr。在學習weak_ptr之…

【C++學習筆記四】運算符重載

當調用一個重載函數和重載運算符時&#xff0c;編譯器通過把您所使用的參數類型和定義中的參數類型相比較&#xff0c;巨鼎選用最合適的定義。&#xff08;重載決策&#xff09; 重載運算符時帶有特殊名稱的函數&#xff0c;函數名是由關鍵字operator和其后要重載的運算符符號…

【C++11新特性】 C++11智能指針之unique_ptr

原創作品&#xff0c;轉載請標明&#xff1a;http://blog.csdn.net/Xiejingfa/article/details/50759210 在前面一篇文章中&#xff0c;我們了解了C11中引入的智能指針之一shared_ptr&#xff0c;今天&#xff0c;我們來介紹一下另一種智能指針unique_ptr。 unique_ptr介紹 uni…