此线程池所依赖的线程类,请参看《一个Windows C++的线程类实现》:

http://blog.csdn.net/huyiyang2010/archive/2010/08/10/5801597.aspx

ThreadPoolExecutor.h

  1. #ifndef __THREAD_POOL_EXECUTOR__
  2. #define __THREAD_POOL_EXECUTOR__
  3. #include "Thread.h"
  4. #include <set>
  5. #include <list>
  6. #include <windows.h>
  7. class CThreadPoolExecutor
  8. {
  9. public:
  10. CThreadPoolExecutor(void);
  11. ~CThreadPoolExecutor(void);
  12. /**
  13. 初始化线程池,创建minThreads个线程
  14. **/
  15. bool Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTaskse);
  16. /**
  17. 执行任务,若当前任务列表没有满,将此任务插入到任务列表,返回true
  18. 若当前任务列表满了,但当前线程数量小于最大线程数,将创建新线程执行此任务,返回true
  19. 若当前任务列表满了,但当前线程数量等于最大线程数,将丢弃此任务,返回false
  20. **/
  21. bool Execute(Runnable * pRunnable);
  22. /**
  23. 终止线程池,先制止塞入任务,
  24. 然后等待直到任务列表为空,
  25. 然后设置最小线程数量为0,
  26. 等待直到线程数量为空,
  27. 清空垃圾堆中的任务
  28. **/
  29. void Terminate();
  30. /**
  31. 返回线程池中当前的线程数量
  32. **/
  33. unsigned int GetThreadPoolSize();
  34. private:
  35. /**
  36. 获取任务列表中的任务,若任务列表为空,返回NULL
  37. **/
  38. Runnable * GetTask();
  39. static unsigned int WINAPI StaticThreadFunc(void * arg);
  40. private:
  41. class CWorker : public CThread
  42. {
  43. public:
  44. CWorker(CThreadPoolExecutor * pThreadPool, Runnable * pFirstTask = NULL);
  45. ~CWorker();
  46. void Run();
  47. private:
  48. CThreadPoolExecutor * m_pThreadPool;
  49. Runnable * m_pFirstTask;
  50. volatile bool m_bRun;
  51. };
  52. typedef std::set<CWorker *> ThreadPool;
  53. typedef std::list<Runnable *> Tasks;
  54. typedef Tasks::iterator TasksItr;
  55. typedef ThreadPool::iterator ThreadPoolItr;
  56. ThreadPool m_ThreadPool;
  57. ThreadPool m_TrashThread;
  58. Tasks m_Tasks;
  59. CRITICAL_SECTION m_csTasksLock;
  60. CRITICAL_SECTION m_csThreadPoolLock;
  61. volatile bool m_bRun;
  62. volatile bool m_bEnableInsertTask;
  63. volatile unsigned int m_minThreads;
  64. volatile unsigned int m_maxThreads;
  65. volatile unsigned int m_maxPendingTasks;
  66. };
  67. #endif

ThreadPoolExecutor.cpp

  1. #include "ThreadPoolExecutor.h"
  2. CThreadPoolExecutor::CWorker::CWorker(CThreadPoolExecutor * pThreadPool, Runnable * pFirstTask) :
  3. m_pThreadPool(pThreadPool),
  4. m_pFirstTask(pFirstTask),
  5. m_bRun(true)
  6. {
  7. }
  8. CThreadPoolExecutor::CWorker::~CWorker()
  9. {
  10. }
  11. /**
  12. 执行任务的工作线程。
  13. 当前没有任务时,
  14. 如果当前线程数量大于最小线程数量,减少线程,
  15. 否则,执行清理程序,将线程类给释放掉
  16. **/
  17. void CThreadPoolExecutor::CWorker::Run()
  18. {
  19. Runnable * pTask = NULL;
  20. while(m_bRun)
  21. {
  22. if(NULL == m_pFirstTask)
  23. {
  24. pTask = m_pThreadPool->GetTask();
  25. }
  26. else
  27. {
  28. pTask = m_pFirstTask;
  29. m_pFirstTask = NULL;
  30. }
  31. if(NULL == pTask)
  32. {
  33. EnterCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
  34. if(m_pThreadPool->GetThreadPoolSize() > m_pThreadPool->m_minThreads)
  35. {
  36. ThreadPoolItr itr = m_pThreadPool->m_ThreadPool.find(this);
  37. if(itr != m_pThreadPool->m_ThreadPool.end())
  38. {
  39. m_pThreadPool->m_ThreadPool.erase(itr);
  40. m_pThreadPool->m_TrashThread.insert(this);
  41. }
  42. m_bRun = false;
  43. }
  44. else
  45. {
  46. ThreadPoolItr itr = m_pThreadPool->m_TrashThread.begin();
  47. while(itr != m_pThreadPool->m_TrashThread.end())
  48. {
  49. (*itr)->Join();
  50. delete (*itr);
  51. m_pThreadPool->m_TrashThread.erase(itr);
  52. itr = m_pThreadPool->m_TrashThread.begin();
  53. }
  54. }
  55. LeaveCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
  56. continue;
  57. }
  58. else
  59. {
  60. pTask->Run();
  61. pTask = NULL;
  62. }
  63. }
  64. }
  65. /////////////////////////////////////////////////////////////////////////////////////////////
  66. CThreadPoolExecutor::CThreadPoolExecutor(void) :
  67. m_bRun(false),
  68. m_bEnableInsertTask(false)
  69. {
  70. InitializeCriticalSection(&m_csTasksLock);
  71. InitializeCriticalSection(&m_csThreadPoolLock);
  72. }
  73. CThreadPoolExecutor::~CThreadPoolExecutor(void)
  74. {
  75. Terminate();
  76. DeleteCriticalSection(&m_csTasksLock);
  77. DeleteCriticalSection(&m_csThreadPoolLock);
  78. }
  79. bool CThreadPoolExecutor::Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTasks)
  80. {
  81. if(minThreads == 0)
  82. {
  83. return false;
  84. }
  85. if(maxThreads < minThreads)
  86. {
  87. return false;
  88. }
  89. m_minThreads = minThreads;
  90. m_maxThreads = maxThreads;
  91. m_maxPendingTasks = maxPendingTasks;
  92. unsigned int i = m_ThreadPool.size();
  93. for(; i<minThreads; i++)
  94. {
  95. //创建线程
  96. CWorker * pWorker = new CWorker(this);
  97. if(NULL == pWorker)
  98. {
  99. return false;
  100. }
  101. EnterCriticalSection(&m_csThreadPoolLock);
  102. m_ThreadPool.insert(pWorker);
  103. LeaveCriticalSection(&m_csThreadPoolLock);
  104. pWorker->Start();
  105. }
  106. m_bRun = true;
  107. m_bEnableInsertTask = true;
  108. return true;
  109. }
  110. bool CThreadPoolExecutor::Execute(Runnable * pRunnable)
  111. {
  112. if(!m_bEnableInsertTask)
  113. {
  114. return false;
  115. }
  116. if(NULL == pRunnable)
  117. {
  118. return false;
  119. }
  120. if(m_Tasks.size() >= m_maxPendingTasks)
  121. {
  122. if(m_ThreadPool.size() < m_maxThreads)
  123. {
  124. CWorker * pWorker = new CWorker(this, pRunnable);
  125. if(NULL == pWorker)
  126. {
  127. return false;
  128. }
  129. EnterCriticalSection(&m_csThreadPoolLock);
  130. m_ThreadPool.insert(pWorker);
  131. LeaveCriticalSection(&m_csThreadPoolLock);
  132. pWorker->Start();
  133. }
  134. else
  135. {
  136. return false;
  137. }
  138. }
  139. else
  140. {
  141. EnterCriticalSection(&m_csTasksLock);
  142. m_Tasks.push_back(pRunnable);
  143. LeaveCriticalSection(&m_csTasksLock);
  144. }
  145. return true;
  146. }
  147. Runnable * CThreadPoolExecutor::GetTask()
  148. {
  149. Runnable * Task = NULL;
  150. EnterCriticalSection(&m_csTasksLock);
  151. if(!m_Tasks.empty())
  152. {
  153. Task = m_Tasks.front();
  154. m_Tasks.pop_front();
  155. }
  156. LeaveCriticalSection(&m_csTasksLock);
  157. return Task;
  158. }
  159. unsigned int CThreadPoolExecutor::GetThreadPoolSize()
  160. {
  161. return m_ThreadPool.size();
  162. }
  163. void CThreadPoolExecutor::Terminate()
  164. {
  165. m_bEnableInsertTask = false;
  166. while(m_Tasks.size() > 0)
  167. {
  168. Sleep(1);
  169. }
  170. m_bRun = false;
  171. m_minThreads = 0;
  172. m_maxThreads = 0;
  173. m_maxPendingTasks = 0;
  174. while(m_ThreadPool.size() > 0)
  175. {
  176. Sleep(1);
  177. }
  178. EnterCriticalSection(&m_csThreadPoolLock);
  179. ThreadPoolItr itr = m_TrashThread.begin();
  180. while(itr != m_TrashThread.end())
  181. {
  182. (*itr)->Join();
  183. delete (*itr);
  184. m_TrashThread.erase(itr);
  185. itr = m_TrashThread.begin();
  186. }
  187. LeaveCriticalSection(&m_csThreadPoolLock);
  188. }

用法:

#include "Thread.h"
#include "ThreadPoolExecutor.h"

class R : public Runnable
{
public:
    ~R()
    {
    }
    void Run()
    {
        printf("Hello World/n");
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    CThreadPoolExecutor * pExecutor = new CThreadPoolExecutor();
    pExecutor->Init(1, 10, 50);
    R r;
    for(int i=0;i<100;i++)
    {
        while(!pExecutor->Execute(&r))
        {
        }
    }
    pExecutor->Terminate();
    delete pExecutor;
    getchar();
    return 0;
}

测试结果:

机器:

Intel(R) Core(TM)2 Duo CPU

E8400 @ 3.00GHz

2G内存

对于100个任务并且每个任务包含10000000个循环,任务中无等待:

单线程执行耗时:2281时间片

单线程池执行耗时:2219时间片

2个线程的线程池耗时:1156时间片

5个线程的线程池耗时:1166时间片

10个线程的线程池耗时:1157时间片

100个线程的线程池耗时:1177时间片

from:

一个Windows C++的线程池的实现的更多相关文章

  1. 分享一个自制的 .net线程池

    扯淡 由于项目需求,需要开发一些程序去爬取一些网站的信息,算是小爬虫程序吧.爬网页这东西是要经过网络传输,如果程序运行起来串行执行请求爬取,会很慢,我想没人会这样做.为了提高爬取效率,必须使用多线程并 ...

  2. windows下利用线程池完成多任务的分配和运行

    在做项目的过程中有时候为了提升效率,用了多线程的方法来对任务进行分割和应用,后来发现,采用线程池的方法能更好的利用线程资源来计算任务,网上有很多关于如何运行线程池的例子,msdn上也给出了对应的例子: ...

  3. 一个简单的python线程池框架

    初学python,实现了一个简单的线程池框架,线程池中除Wokers(工作线程)外,还单独创建了一个日志线程,用于日志的输出.线程间采用Queue方式进行通信. 代码如下:(不足之处,还请高手指正) ...

  4. 一个简单的linux线程池(转-wangchenxicool)

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

  5. 一个Linux下C线程池的实现

    什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了.如果线程创建和销毁时间相比任 ...

  6. 一个boost底下的线程池

    Boost的thread库中目前并没有提供线程池,我在sorceforge上找了一个用boost编写的线程池.该线程池和boost结合的比较好,并且提供了多种任务执行策略,使用也非常简单. 下载地址: ...

  7. 一个Work Stealing Pool线程池的实现

    一.一般来说实现一个线程池主要包括以下几个组成部分: 1)线程管理器 :用于创建并管理线程池 . 2)工作线程 :线程池中实际执行任务的线程 . 在初始化线程时会预先创建好固定数目的线程在池中 ,这些 ...

  8. Windows下一个比较完美的线程池实现(使用线程池实现的Http上传下载实现)

    http://blog.csdn.net/fishjam/article/details/8632049 http://download.csdn.net/user/fishjam

  9. 一个Windows C++的线程类实现

    Thread.h [cpp] view plaincopy #ifndef __THREAD_H__ #define __THREAD_H__ #include <string> #inc ...

随机推荐

  1. 引用 - PHP手册笔记

    引用是什么 PHP中的引用意味着,用不同的变量名访问同一变量内容,类似于Unix的文件名和文件本身(变量名是目录条目,变量内容是文件本身,即用不同的目录条目访问同一文件),可以看做Unix文件系统中的 ...

  2. 今日哈工大刷推荐python脚本

    import httplib import random import time import urllib2 import re address = raw_input("Please i ...

  3. SQL Server 查看identity值的几种方法。

    方法 1. ident_incr('Table_name');#  增量    identity(A,B) 中的B值 ident_seed('Table_name'); # 种子    identit ...

  4. 站在巨人的肩膀上,C++开源库大全

    程序员要站在巨人的肩膀上,C++拥有丰富的开源库,这里包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++ Standard Library:是一系列 ...

  5. Boost程序库完全开发指南——深入C++“准”标准库(第3版)

    内容简介  · · · · · · Boost 是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉. Boost 由C++标准委员会部分成员所设立的Bo ...

  6. POSIX和SYSTEM的消息队列应该注意的问题

    首先看看POSIX的代码: 1.posix_mq_server.c #include <mqueue.h>#include <sys/stat.h>#include <s ...

  7. 杭电oj 3079 Vowel Counting

    Tips:可以先将输入的字符串全部转化为小写字母,然后再将元音字母变为大写,时间复杂度O(n) #include<stdio.h> #include<string.h> #in ...

  8. .Net 缓存依赖详解

    缓存命名空间的讲解流程 16.1  System.Web.Caching简介 本节从缓存命名空间的总体简介和组成结构入手,从整体上对System.Web.Caching进行概述. 16.1.1  Sy ...

  9. Backup Exec Inventory 与Catalog的含义(转载)

    编录:即catalog,就是让磁带机读取磁带之前所备份过的内容的目录列表,可以让你知道之前做过什么备份,以及备份时间等详细信息. 列清单:inventory,跟编录是不同,inventory是查询磁带 ...

  10. L13 DNS

    DNS: 根 root 分布式. 服务于终端客户,也服务于其他dns服务器.对其他dns服务器提供数据 是域名资料数据库,也是解析服务提供者.用户接入进来,可以得到解析的服务 仅管理下一级dns服务器 ...