




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一个Linux下C线程池的实现2009-01-05 21:18 什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。 下面是Linux系统下用C语言创建的一个线程池。线程池会维护一个任务链表(每个CThread_worker结构就是一个任务)。 pool_init()函数预先创建好max_thread_num个线程,每个线程执thread_routine ()函数。该函数中1. while (pool-cur_queue_size = 0) 2. 3. pthread_cond_wait (&(pool-queue_ready),&(pool-queue_lock); 4. 表示如果任务链表中没有任务,则该线程出于阻塞等待状态。否则从队列中取出任务并执行。 pool_add_worker()函数向线程池的任务链表中加入一个任务,加入后通过调用pthread_cond_signal (&(pool-queue_ready)唤醒一个出于阻塞状态的线程(如果有的话)。 pool_destroy ()函数用于销毁线程池,线程池任务链表中的任务不会再被执行,但是正在运行的线程会一直把任务运行完后再退出。下面贴出完整代码1. #include 2. #include 3. #include 4. #include 5. #include 6. #include 7.8. /* 9. *线程池里所有运行和等待的任务都是一个CThread_worker 10. *由于所有任务都在链表里,所以是一个链表结构 11. */ 12. typedef struct worker 13. 14. /*回调函数,任务运行时会调用此函数,注意也可声明成其它形式*/ 15. void *(*process) (void *arg); 16. void *arg;/*回调函数的参数*/ 17. struct worker *next; 18.19. CThread_worker; 20.21.22. /*线程池结构*/ 23. typedef struct 24. 25. pthread_mutex_t queue_lock; 26. pthread_cond_t queue_ready; 27.28. /*链表结构,线程池中所有等待任务*/ 29. CThread_worker *queue_head; 30.31. /*是否销毁线程池*/ 32. int shutdown; 33. pthread_t *threadid; 34. /*线程池中允许的活动线程数目*/ 35. int max_thread_num; 36. /*当前等待队列的任务数目*/ 37. int cur_queue_size; 38.39. CThread_pool; 40.41.42. int pool_add_worker (void *(*process) (void *arg), void *arg); 43. void *thread_routine (void *arg); 44.45.46. static CThread_pool *pool = NULL; 47. void 48. pool_init (int max_thread_num) 49. 50. pool = (CThread_pool *) malloc (sizeof (CThread_pool); 51.52. pthread_mutex_init (&(pool-queue_lock), NULL); 53. pthread_cond_init (&(pool-queue_ready), NULL); 54.55. pool-queue_head = NULL; 56.57. pool-max_thread_num = max_thread_num; 58. pool-cur_queue_size = 0; 59.60. pool-shutdown = 0; 61.62. pool-threadid = 63. (pthread_t *) malloc (max_thread_num * sizeof (pthread_t); 64. int i = 0; 65. for (i = 0; i threadidi), NULL, thread_routine, 68. NULL); 69. 70. 71.72.73. /*向线程池中加入任务*/ 74. int 75. pool_add_worker (void *(*process) (void *arg), void *arg) 76. 77. /*构造一个新任务*/ 78. CThread_worker *newworker = 79. (CThread_worker *) malloc (sizeof (CThread_worker); 80. newworker-process = process; 81. newworker-arg = arg; 82. newworker-next = NULL;/*别忘置空*/ 83.84. pthread_mutex_lock (&(pool-queue_lock); 85. /*将任务加入到等待队列中*/ 86. CThread_worker *member = pool-queue_head; 87. if (member != NULL) 88. 89. while (member-next != NULL) 90. member = member-next; 91. member-next = newworker; 92. 93. else 94. 95. pool-queue_head = newworker; 96. 97.98. assert (pool-queue_head != NULL); 99.100. pool-cur_queue_size+; 101. pthread_mutex_unlock (&(pool-queue_lock); 102. /*好了,等待队列中有任务了,唤醒一个等待线程; 103. 注意如果所有线程都在忙碌,这句没有任何作用*/ 104. pthread_cond_signal (&(pool-queue_ready); 105. return 0; 106. 107.108.109. /*销毁线程池,等待队列中的任务不会再被执行,但是正在运行的线程会一直 110. 把任务运行完后再退出*/ 111. int 112. pool_destroy () 113. 114. if (pool-shutdown) 115. return -1;/*防止两次调用*/ 116. pool-shutdown = 1; 117.118. /*唤醒所有等待线程,线程池要销毁了*/ 119. pthread_cond_broadcast (&(pool-queue_ready); 120.121. /*阻塞等待线程退出,否则就成僵尸了*/ 122. int i; 123. for (i = 0; i max_thread_num; i+) 124. pthread_join (pool-threadidi, NULL); 125. free (pool-threadid); 126.127. /*销毁等待队列*/ 128. CThread_worker *head = NULL; 129. while (pool-queue_head != NULL) 130. 131. head = pool-queue_head; 132. pool-queue_head = pool-queue_head-next; 133. free (head); 134. 135. /*条件变量和互斥量也别忘了销毁*/ 136. pthread_mutex_destroy(&(pool-queue_lock); 137. pthread_cond_destroy(&(pool-queue_ready); 138. 139. free (pool); 140. /*销毁后指针置空是个好习惯*/ 141. pool=NULL; 142. return 0; 143. 144.145.146. void * 147. thread_routine (void *arg) 148. 149. printf (starting thread 0x%xn, pthread_self (); 150. while (1) 151. 152. pthread_mutex_lock (&(pool-queue_lock); 153. /*如果等待队列为0并且不销毁线程池,则处于阻塞状态; 注意 154. pthread_cond_wait是一个原子操作,等待前会解锁,唤醒后会加锁*/ 155. while (pool-cur_queue_size = 0 & !pool-shutdown) 156. 157. printf (thread 0x%x is waitingn, pthread_self (); 158. pthread_cond_wait (&(pool-queue_ready), &(pool-queue_lock); 159. 160.161. /*线程池要销毁了*/ 162. if (pool-shutdown) 163. 164. /*遇到break,continue,return等跳转语句,千万不要忘记先解锁*/ 165. pthread_mutex_unlock (&(pool-queue_lock); 166. printf (thread 0x%x will exitn, pthread_self (); 167. pthread_exit (NULL); 168. 169.170. printf (thread 0x%x is starting to workn, pthread_self (); 171.172. /*assert是调试的好帮手*/ 173. assert (pool-cur_queue_size != 0); 174. assert (pool-queue_head != NULL); 175. 176. /*等待队列长度减去1,并取出链表中的头元素*/ 177. pool-cur_queue_size-; 178. CThread_worker *worker = pool-queue_head; 179. pool-queue_head = worker-next; 180. pthread_mutex_unlock (&(pool-queue_lock); 181.182. /*调用回调函数,执行任务*/ 183. (*(worker-process) (worker-arg); 184. free (worker); 185. worker = NULL; 186. 187. /*这一句应该是不可达的*/ 188. pthread_exit (NULL); 189. 190. 下面是测试代码1. void * 2. myprocess (void *arg) 3. 4. printf (threadid is 0x%x, working on task %dn, pthread_self (),*(int *) arg); 5. sleep (1);/*休息一秒,延长任务的执行时间*/ 6. return NULL; 7. 8.9. int 10. main (int argc, char *argv) 11. 12. pool_init (3);/*线程池中最多三个活动线程*/ 13. 14. /*连续向池中投入10个任务*/ 15. int *workingnum = (int *) malloc (sizeof (int) * 10); 16. int i; 17. for (i = 0; i 10; i+) 18. 19. workingnumi = i; 20. pool_add_worker (myprocess, &workingnumi); 21. 22. /*等待所有任务完成*/ 23. sleep (5); 24. /*销毁线程池*/ 25. pool_destroy (); 26.27. free (workingnum); 28. return 0; 29. 将上述所有代码放入threadpool.c文件中,在Linux输入编译命令$ gcc -o threadpool threadpool.c -lpthread以下是运行结果starting thread 0xb7df6b90thread 0xb7df6b90 is waitingstarting thread 0xb75f5b90thread 0xb75f5b90 is waitingstarting thread 0xb6df4b90thread 0xb6df4b90 is waitingthread 0xb7df6b90 is starting to workthreadid is 0xb7df6b90, working on task 0thread 0xb75f5b90 is starting to workthreadid is 0xb75f5b90, working on task 1thread 0xb6df4b90 is starting to workthreadid is 0xb6df4b90, working on task 2thread 0xb7df6b90 is starting to workthreadid is 0xb7df6b90
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年戊二酮苯项目发展计划
- 2025年气象、水文仪器及装置项目建议书
- 教育技术推动现代课程设计的核心力量
- 2025年河北省鹿泉一中物理高二下期末调研试题含解析
- 中职新媒体营销课件
- 商业案例分析丰富多样的学习资源助力企业发展
- 中职数学直线复习课件
- 探索教育数字化转型中的技术力量
- 教育心理学在学生自我管理中的应用案例
- 中职教育政策宣讲课件
- 职业病防治计划实施检查表
- 江苏省南京市雨花台区2024-2025学年五年级下学期期末英语试题
- 小麦检验培训课件
- 2024年12月英语四级真题及答案-第3套
- 既有居住建筑节能改造实施方案
- 2025年湖南省高考物理试卷真题(含答案解析)
- 2025年中国东航旗下东方航空食品投资有限公司招聘笔试参考题库含答案解析
- 农业肥料溯源管理制度
- T/CCS 076-2023煤矿井下钻孔浆体充填技术要求
- 唾液腺肿瘤护理
- 行走的医院乡村巡回医疗健康服务规范
评论
0/150
提交评论