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

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

SystemThreadPool.h

  1. #define __SYSTEM_THREAD_POOL__
  2. #include "Thread.h"
  3. #include <list>
  4. #include <windows.h>
  5. class CThreadPoolExecutor
  6. {
  7. public:
  8. CThreadPoolExecutor(void);
  9. ~CThreadPoolExecutor(void);
  10. /**
  11. 初始化线程池,创建minThreads个线程
  12. **/
  13. bool Init(unsigned int maxTaskse);
  14. /**
  15. 执行任务,若当前任务列表没有满,将此任务插入到任务列表,返回true
  16. 否则返回false
  17. **/
  18. bool Execute(Runnable * pRunnable);
  19. /**
  20. 终止线程池,先制止塞入任务,
  21. 然后等待直到任务列表为空,
  22. 然后设置最小线程数量为0,
  23. 等待直到线程数量为空,
  24. 清空垃圾堆中的任务
  25. **/
  26. void Terminate();
  27. /**
  28. 返回线程池中当前的线程数量
  29. **/
  30. unsigned int GetThreadPoolSize();
  31. private:
  32. static unsigned int WINAPI StaticThreadFunc(void * arg);
  33. private:
  34. typedef std::list<Runnable *> Tasks;
  35. typedef Tasks::iterator TasksItr;
  36. Tasks m_Tasks;
  37. CRITICAL_SECTION m_csTasksLock;
  38. volatile bool m_bRun;
  39. volatile bool m_bEnableInsertTask;
  40. volatile unsigned int m_maxTasks;
  41. };
  42. #endif

SytemThreadPool.cpp

  1. #include "SystemThreadPool.h"
  2. CThreadPoolExecutor::CThreadPoolExecutor(void) :
  3. m_bRun(false),
  4. m_bEnableInsertTask(false)
  5. {
  6. InitializeCriticalSection(&m_csTasksLock);
  7. }
  8. CThreadPoolExecutor::~CThreadPoolExecutor(void)
  9. {
  10. Terminate();
  11. DeleteCriticalSection(&m_csTasksLock);
  12. }
  13. bool CThreadPoolExecutor::Init(unsigned int maxTasks)
  14. {
  15. if(maxTasks == 0)
  16. {
  17. return false;
  18. }
  19. m_maxTasks = maxTasks;
  20. m_bRun = true;
  21. m_bEnableInsertTask = true;
  22. return true;
  23. }
  24. bool CThreadPoolExecutor::Execute(Runnable * pRunnable)
  25. {
  26. if(!m_bEnableInsertTask)
  27. {
  28. return false;
  29. }
  30. if(NULL == pRunnable)
  31. {
  32. return false;
  33. }
  34. EnterCriticalSection(&m_csTasksLock);
  35. if(m_Tasks.size() >= m_maxTasks)
  36. {
  37. LeaveCriticalSection(&m_csTasksLock);
  38. return false;
  39. }
  40. m_Tasks.push_back(pRunnable);
  41. LeaveCriticalSection(&m_csTasksLock);
  42. bool ret = QueueUserWorkItem((LPTHREAD_START_ROUTINE)StaticThreadFunc, this, WT_EXECUTEINPERSISTENTIOTHREAD);
  43. if(!ret)
  44. {
  45. EnterCriticalSection(&m_csTasksLock);
  46. m_Tasks.remove(pRunnable);
  47. LeaveCriticalSection(&m_csTasksLock);
  48. }
  49. return ret;
  50. }
  51. unsigned int CThreadPoolExecutor::GetThreadPoolSize()
  52. {
  53. return m_Tasks.size();
  54. }
  55. void CThreadPoolExecutor::Terminate()
  56. {
  57. m_bEnableInsertTask = false;
  58. m_bRun = false;
  59. while(m_Tasks.size() != 0)
  60. {
  61. Sleep(1);
  62. }
  63. }
  64. unsigned int WINAPI CThreadPoolExecutor::StaticThreadFunc(void * arg)
  65. {
  66. CThreadPoolExecutor * pThreadPool = (CThreadPoolExecutor *)arg;
  67. Runnable * pRunnable = NULL;
  68. EnterCriticalSection(&pThreadPool->m_csTasksLock);
  69. pRunnable = pThreadPool->m_Tasks.front();
  70. if(NULL != pRunnable)
  71. {
  72. pThreadPool->m_Tasks.pop_front();
  73. }
  74. LeaveCriticalSection(&pThreadPool->m_csTasksLock);
  75. if(NULL != pRunnable)
  76. {
  77. pRunnable->Run();
  78. }
  79. return 0;
  80. }

用法:

#include "Thread.h"
#include "SystemThreadPool.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(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个循环,任务中无等待:

线程池耗时:2203时间片

from:http://blog.csdn.net/huyiyang2010/article/details/5820548

使用QueueUserWorkerItem实现的线程池封装的更多相关文章

  1. jedis使用线程池封装redis基本操作

    redisclient jedis 经常使用的 操作 key value hash list set zset 的基本操作 package cn.zto.util; import java.util. ...

  2. Java开发笔记(一百零四)普通线程池的运用

    前面介绍了线程的基本用法,以及多线程并发的问题处理,但实际开发中往往存在许多性质相似的任务,比如批量发送消息.批量下载文件.批量进行交易等等.这些同类任务的处理流程一致,不存在资源共享问题,相互之间也 ...

  3. Java ExecutorService四种线程池及自定义ThreadPoolExecutor机制

    一.Java 线程池 Java通过Executors提供四种线程池,分别为:1.newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收 ...

  4. 谈谈Java的线程池设计

    在实际项目中,如果因为想异步执行暂时性的任务而不断创建线程是很浪费资源的事情(当一个任务执行完后,线程也没用了).这种情况下,最好是将任务提交给线程池执行. 所谓池,就是将管理某一种资源,对资源进行复 ...

  5. 进程池与线程池基本使用、协程理论与实操、IO模型、前端、BS架构、HTTP协议与HTML前戏

    昨日内容回顾 GIL全局解释器锁 1.在python解释器中 才有GIL的存在(只与解释器有关) 2.GIL本质上其实也是一把互斥锁(并发变串行 牺牲效率保证安全) 3.GIL的存在 是由于Cpyth ...

  6. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  7. c++封装编写线程池

    在csapp学习或者其他linux底层编程的过程中,一般都会举一些多线程或多进程的例子,配合底层同步原语.系统调用api来解释怎么创建多线程/多进程. 但是这些例子和实际项目中所用到的多线程/多进程编 ...

  8. 面向对象的线程池Threadpool的封装

    线程池是一种多线程处理形式,预先创建好一定数量的线程,将其保存于一个容器中(如vector), 处理过程中将任务添加到队列,然后从容器中取出线程后自动启动这些任务,具体实现如下. 以下是UML图,展示 ...

  9. 线程池、及使用场景、线程安全封装、ConcurrentHashMap应用场景

    https://blog.csdn.net/sinbadfreedom/article/details/80467253  :1.HashMap与ConcurrentHashMap的区别与应用场景 h ...

随机推荐

  1. gulp配置版本号 教程之gulp-rev-append

    简介: 使用gulp-rev-append给页面的引用添加版本号,清除页面引用缓存. 1.安装nodejs/全局安装gulp/项目安装gulp/创建package.json和gulpfile.js文件 ...

  2. PHPMailer发送邮件方法

    /** * * 测试邮件发送s * @param 服务器 $Host * @param 端口 $Port * @param 昵称 $Fromname * @param 身份验证用户名 $Usernam ...

  3. Git 操作常用命令

    Git使用 1. git pull    更新服务器代码到本地a). git pull origin master是将origin这个版本库的代码更新到本地的master主分支 2. git push ...

  4. Mining 任务分类

    1.预测任务: 根据其它属性的值预测特定属性的值. 2.描述性任务: 发现数据之间潜在的关联关系.

  5. Oracle EBS-SQL (BOM-10):检查有BOM无计划员的数据.sql

    select DISTINCT     msi.segment1 编码    ,msi.description 描述    ,msi.item_type 物料类型    ,msi.inventory_ ...

  6. QueryString和BASE64

    加号(+)是BASE64编码的一部分,而加号在QueryString中被当成是空格.因此,当一个含有BASE64编码的字符串直接作为URL的一部分时,如果其中含有加号,则使用QueryString读取 ...

  7. VC 窗口出现白屏闪烁的解决办法

    处理一下窗口的WM_ERASEBKGND消息即可. 在messagemap里添加ON_WM_ERASEBKGND() 在窗口头文件里添加 afx_msg BOOL OnEraseBkgnd(CDC* ...

  8. Delphi使用XmlHttp获取时间

    uses ComObj, DateUtils; procedure TForm1.Button1Click(Sender: TObject); var XmlHttp: Variant; datetx ...

  9. EF 6 调用存储过程时返回多结果集和OUTPUT参数问题

    原文地址:http://q.cnblogs.com/q/56836/ 各位大侠,提问一个关于EF6调用存储过程时返回多结果集和OUTPUT参数问题 目前已经可以调用存储过程并且可以返回多个结果集. 但 ...

  10. yum localinstall rpm