线程池:简单地说,线程池 就是预先创建好一批线程,方便、快速地处理收到的业务。比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高。

在linux中,使用的是posix线程库,首先介绍几个常用的函数:

1 线程的创建和取消函数

pthread_create

创建线程

pthread_join

合并线程

pthread_cancel

取消线程

2 线程同步函数

pthread_mutex_lock

pthread_mutex_unlock

pthread_cond_signal

pthread_cond_wait

关于函数的详细说明,参考man手册

线程池的实现:

线程池的实现主要分为三部分,线程的创建、添加任务到线程池中、工作线程从任务队列中取出任务进行处理。

主要有两个类来实现,CTask,CThreadPool

/**
执行任务的类,设置任务数据并执行
**/

C代码  
  1. class CTask
  2. {
  3. protected:
  4. string m_strTaskName;  //任务的名称
  5. void* m_ptrData;       //要执行的任务的具体数据
  6. public:
  7. CTask(){}
  8. CTask(string taskName)
  9. {
  10. this->m_strTaskName = taskName;
  11. m_ptrData = NULL;
  12. }
  13. virtual int Run()= 0;
  14. void SetData(void* data);    //设置任务数据
  15. };

任务类是个虚类,所有的任务要从CTask类中继承 ,实现run接口,run接口中需要实现的就是具体解析任务的逻辑。m_ptrData是指向任务数据的指针,可以是简单数据类型,也可以是自定义的复杂数据类型。

线程池类

/**
线程池
**/

Java代码  
  1. class CThreadPool
  2. {
  3. private:
  4. vector<CTask*> m_vecTaskList;         //任务列表
  5. int m_iThreadNum;                            //线程池中启动的线程数
  6. static vector<pthread_t> m_vecIdleThread;   //当前空闲的线程集合
  7. static vector<pthread_t> m_vecBusyThread;   //当前正在执行的线程集合
  8. static pthread_mutex_t m_pthreadMutex;    //线程同步锁
  9. static pthread_cond_t m_pthreadCond;    //线程同步的条件变量
  10. protected:
  11. static void* ThreadFunc(void * threadData); //新线程的线程函数
  12. static int MoveToIdle(pthread_t tid);   //线程执行结束后,把自己放入到空闲线程中
  13. static int MoveToBusy(pthread_t tid);   //移入到忙碌线程中去
  14. int Create();          //创建所有的线程
  15. public:
  16. CThreadPool(int threadNum);
  17. int AddTask(CTask *task);      //把任务添加到线程池中
  18. int StopAll();
  19. };

当线程池对象创建后,启动一批线程,并把所有的线程放入空闲列表中,当有任务到达时,某一个线程取出任务并进行处理。

线程之间的同步用线程锁和条件变量。

这个类的对外接口有两个:

AddTask函数把任务添加到线程池的任务列表中,并通知线程进行处理。当任务到到时,把任务放入m_vecTaskList任务列表中,并用pthread_cond_signal唤醒一个线程进行处理。

StopAll函数停止所有的线程

Cpp代码  
  1. ************************************************
  2. 代码:
  3. ××××××××××××××××××××CThread.h
  4. #ifndef __CTHREAD
  5. #define __CTHREAD
  6. #include <vector>
  7. #include <string>
  8. #include <pthread.h>
  9. using namespace std;
  10. /**
  11. 执行任务的类,设置任务数据并执行
  12. **/
  13. class CTask
  14. {
  15. protected:
  16. string m_strTaskName;  //任务的名称
  17. void* m_ptrData;       //要执行的任务的具体数据
  18. public:
  19. CTask(){}
  20. CTask(string taskName)
  21. {
  22. this->m_strTaskName = taskName;
  23. m_ptrData = NULL;
  24. }
  25. virtual int Run()= 0;
  26. void SetData(void* data);    //设置任务数据
  27. };
  28. /**
  29. 线程池
  30. **/
  31. class CThreadPool
  32. {
  33. private:
  34. vector<CTask*> m_vecTaskList;         //任务列表
  35. int m_iThreadNum;                            //线程池中启动的线程数
  36. static vector<pthread_t> m_vecIdleThread;   //当前空闲的线程集合
  37. static vector<pthread_t> m_vecBusyThread;   //当前正在执行的线程集合
  38. static pthread_mutex_t m_pthreadMutex;    //线程同步锁
  39. static pthread_cond_t m_pthreadCond;    //线程同步的条件变量
  40. protected:
  41. static void* ThreadFunc(void * threadData); //新线程的线程函数
  42. static int MoveToIdle(pthread_t tid);   //线程执行结束后,把自己放入到空闲线程中
  43. static int MoveToBusy(pthread_t tid);   //移入到忙碌线程中去
  44. int Create();          //创建所有的线程
  45. public:
  46. CThreadPool(int threadNum);
  47. int AddTask(CTask *task);      //把任务添加到线程池中
  48. int StopAll();
  49. };
  50. #endif
  51. 类的实现为:
  52. ××××××××××××××××××××CThread.cpp
  53. #include "CThread.h"
  54. #include <string>
  55. #include <iostream>
  56. using namespace std;
  57. void CTask::SetData(void * data)
  58. {
  59. m_ptrData = data;
  60. }
  61. vector<pthread_t> CThreadPool::m_vecBusyThread;
  62. vector<pthread_t> CThreadPool::m_vecIdleThread;
  63. pthread_mutex_t CThreadPool::m_pthreadMutex = PTHREAD_MUTEX_INITIALIZER;
  64. pthread_cond_t CThreadPool::m_pthreadCond = PTHREAD_COND_INITIALIZER;
  65. CThreadPool::CThreadPool(int threadNum)
  66. {
  67. this->m_iThreadNum = threadNum;
  68. Create();
  69. }
  70. int CThreadPool::MoveToIdle(pthread_t tid)
  71. {
  72. vector<pthread_t>::iterator busyIter = m_vecBusyThread.begin();
  73. while(busyIter != m_vecBusyThread.end())
  74. {
  75. if(tid == *busyIter)
  76. {
  77. break;
  78. }
  79. busyIter++;
  80. }
  81. m_vecBusyThread.erase(busyIter);
  82. m_vecIdleThread.push_back(tid);
  83. return 0;
  84. }
  85. int CThreadPool::MoveToBusy(pthread_t tid)
  86. {
  87. vector<pthread_t>::iterator idleIter = m_vecIdleThread.begin();
  88. while(idleIter != m_vecIdleThread.end())
  89. {
  90. if(tid == *idleIter)
  91. {
  92. break;
  93. }
  94. idleIter++;
  95. }
  96. m_vecIdleThread.erase(idleIter);
  97. m_vecBusyThread.push_back(tid);
  98. return 0;
  99. }
  100. void* CThreadPool::ThreadFunc(void * threadData)
  101. {
  102. pthread_t tid = pthread_self();
  103. while(1)
  104. {
  105. pthread_mutex_lock(&m_pthreadMutex);
  106. pthread_cond_wait(&m_pthreadCond,&m_pthreadMutex);
  107. cout << "tid:" << tid << " run" << endl;
  108. //get task
  109. vector<CTask*>* taskList = (vector<CTask*>*)threadData;
  110. vector<CTask*>::iterator iter = taskList->begin();
  111. while(iter != taskList->end())
  112. {
  113. MoveToBusy(tid);
  114. break;
  115. }
  116. CTask* task = *iter;
  117. taskList->erase(iter);
  118. pthread_mutex_unlock(&m_pthreadMutex);
  119. cout << "idel thread number:" << CThreadPool::m_vecIdleThread.size() << endl;
  120. cout << "busy thread number:" << CThreadPool::m_vecBusyThread.size() << endl;
  121. //cout << "task to be run:" << taskList->size() << endl;
  122. task->Run();
  123. //cout << "CThread::thread work" << endl;
  124. cout << "tid:" << tid << " idle" << endl;
  125. }
  126. return (void*)0;
  127. }
  128. int CThreadPool::AddTask(CTask *task)
  129. {
  130. this->m_vecTaskList.push_back(task);
  131. pthread_cond_signal(&m_pthreadCond);
  132. return 0;
  133. }
  134. int CThreadPool::Create()
  135. {
  136. for(int i = 0; i < m_iThreadNum;i++)
  137. {
  138. pthread_t tid = 0;
  139. pthread_create(&tid,NULL,ThreadFunc,&m_vecTaskList);
  140. m_vecIdleThread.push_back(tid);
  141. }
  142. return 0;
  143. }
  144. int CThreadPool::StopAll()
  145. {
  146. vector<pthread_t>::iterator iter = m_vecIdleThread.begin();
  147. while(iter != m_vecIdleThread.end())
  148. {
  149. pthread_cancel(*iter);
  150. pthread_join(*iter,NULL);
  151. iter++;
  152. }
  153. iter = m_vecBusyThread.begin();
  154. while(iter != m_vecBusyThread.end())
  155. {
  156. pthread_cancel(*iter);
  157. pthread_join(*iter,NULL);
  158. iter++;
  159. }
  160. return 0;
  161. }
  162. 简单示例:
  163. ××××××××test.cpp
  164. #include "CThread.h"
  165. #include <iostream>
  166. using namespace std;
  167. class CWorkTask: public CTask
  168. {
  169. public:
  170. CWorkTask()
  171. {}
  172. int Run()
  173. {
  174. cout << (char*)this->m_ptrData << endl;
  175. sleep(10);
  176. return 0;
  177. }
  178. };
  179. int main()
  180. {
  181. CWorkTask taskObj;
  182. char szTmp[] = "this is the first thread running,haha success";
  183. taskObj.SetData((void*)szTmp);
  184. CThreadPool threadPool(10);
  185. for(int i = 0;i < 11;i++)
  186. {
  187. threadPool.AddTask(&taskObj);
  188. }
  189. while(1)
  190. {
  191. sleep(120);
  192. }
  193. return 0;
  194. }

一个简单的linux线程池相关推荐

  1. 美团简单版动态线程池源码实现

    背景 动态线程池,指的是线程池中的参数可以动态修改并生效,比如corePoolSize.maximumPoolSize等. 在工作中,线程池的核心线程数和最大线程数等参数是很难估计和固定的,如果能在应 ...

  2. linux线程池简单实例

    linux线程池简单实例 转载于:https://www.cnblogs.com/adong7639/p/5044685.html

  3. 手撸一款简单高效的线程池(五)

    在之前的内容中,我们给大家介绍了 C++实现线程池过程中的一些常用线优化方案,并分析了不同机制使用时的利弊.这一篇,是线程池系列的最后一章.我们会介绍一下 CGraph 中的 threadpool 如 ...

  4. 《Linux内核分析》 第三周 构造一个简单的Linux系统MenuOS

    Linux内核分析 第三周 构造一个简单的Linux系统MenuOS 张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...

  5. 制作一个简单的linux

    我这里是借助宿主机做的一个简单的Linux,我们只要知道一个Linux启动过程需要什么,这里制作就简单的多了.不过没有基础的也没关系,我写的很详细,没有基础的看了我写的步骤只要细心也是会做出来的,我这 ...

  6. 网络缓冲 linux,一个简单的linux缓冲区利用

    一个简单的linux缓冲区利用by Netfairy - 2016-02-28 刚开始接触linux下的漏洞利用,先做个练练手.程序源码如下: #include #include #include i ...

  7. linux线程池实现多线程并发,基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF...

    基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF 第 卷 第 期 电子设计工程 年 月 基于 的多线程池并发 服务器设计 陈 涛 任海兰 武汉邮电科学研究院 湖北 武汉 摘要 时至今 ...

  8. 非常精简的Linux线程池实现(一)——使用互斥锁和条件变量

    https://blog.csdn.net/kxcfzyk/article/details/31719687 线程池的含义跟它的名字一样,就是一个由许多线程组成的池子. 有了线程池,在程序中使用多线程 ...

  9. linux线程池的使用

      Linux下通用线程池的创建与使用[ZT] 收藏 本文给出了一个通用的线程池框架,该框 架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执 ...

最新文章

  1. object-c中管理文件和目录:NSFileManager使用方法
  2. 送餐机器人市场达11.6亿 美团将成“搅局者”?
  3. python画图代码星星-Python利用for循环打印星号三角形的案例
  4. 声腔设计中无前腔的影响
  5. 对学校的希望和寄语_新年元旦寄语【三篇】
  6. socket.io 中文手册 socket.io 中文文档
  7. PyCharm入门教程——在编辑器中选择文本
  8. mysql镜像压缩包使用_如何连接docker的mysql镜像
  9. SAP Basis Consultant Job Role
  10. 清除无用工具栏:CommandbarCleaner下载
  11. PHP判断文件夹是否存在和创建文件夹的方法
  12. senchaTouch 给组件传参的两种方式
  13. 一个WIFI热点的脚本思路,顺记shell知识
  14. Android现学现用第十二天
  15. creator html富文本_小程序之HTML富文本解析
  16. mysql 异步同步_MySQL主从复制异步半同步实例
  17. php ziparchive类,PHP Zip ZipArchive 类_编程学问网
  18. 原则与思维模型--《思维模型》0
  19. Fastjson漏洞修复参考
  20. 分布式项目Maven打包出现Could not resolve dependencies for project、Could not find artifact问题解决

热门文章

  1. SpringMVC第五次课 SSM整合
  2. 什么推动当今品牌的忠诚度
  3. java架构师眼中的高并发架构
  4. 权重随机算法的java实现
  5. android 按键会触发ontouch吗?_这次,我把Android事件分发机制翻了个遍
  6. 跟我一起使用electron搭建一个文件浏览器吧
  7. 《leetcode》pascals-triangle(杨辉三角)
  8. 《网易编程题》疯狂队列
  9. 逻辑推理篇:数据分析中违背常理的悖论:辛普森悖论
  10. Scala入门到精通——第十八节 隐式转换与隐式参数(一)