此线程池所依赖的线程类,请参看《一个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. HTML5新属性

    1.contenteditable 属性指定元素内容是否可编辑. 注意: 当元素中没有设置 contenteditable 属性时,元素将从父元素继承. 所有主流浏览器都支持 contentedita ...

  2. Python成长之路第一篇(3)_初识字典

    经过上章的学习我们已经了解到了列表可以通过索引来获取对应的值,在本章我们将学到通过名字来索引数据,这种结构的类型称之为映射(maooing),在Python中字典是唯一内建的映射类型,其中的值我们称之 ...

  3. Java之线程的控制

    1. join线程: 在线程执行过程中,有时想让另一个线程先执行,比如将一大问题分割成许多小问题,给每一个小问题分配线程,但所有小问题处理完后再让主线程进一步操作.此时我们可以在主线程中调用其它线程的 ...

  4. js 概念(构造函数)

    所有关于类.对象的语言里面,都有构造函数的概念,其实构造函数,就是在创建这个对象或者类的实例时候自动调用的函数,一般的语言都是new创建,那么new的参数就传递给构造函数.

  5. TPen的7种Style和16种Mode

    //TPen 的主要属性有四: Color.Width.Style.Mode {Color: 颜色} {Width: 宽度; 默认是 1; 如果赋予 <= 0 的值, 会使用默认值} {Styl ...

  6. Delphi多线程数据库查询(ADO)

    ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用(CoInitialize was not called):所以,在使用任何dbGo对象前,必须手 调用CoIniti ...

  7. jquery中read与js中onload区别

    在JavaScript中,onload函数是最经常使用的,几乎涉及到JavaScript的童鞋都少不了要接触它.这个函数的作用就是等待网页完全装载完了以后再去执行代码块内的语句,因为按照文档流的执行顺 ...

  8. 把war包放到Tomcat安装文件夹下,不能直接訪问的解决方式

    临床表现: Tomcat启动后首页能訪问(http://localhost:8080/). 将自己写的一个webprojectwar包放到Tomcat安装文件夹下的/webapps以下(比方hello ...

  9. UITabBarController 笔记(二) ViewController中加UITabBarController

    新建一个简单视图iOS工程,在ViewController的viewDidLoad中代码如下 - (void)viewDidLoad { [super viewDidLoad]; // Do any ...

  10. v​s​快​捷​键

    Ctrl+E,D ----格式化全部代码 Ctrl+A+K+FCtrl+E,F ----格式化选中的代码 Ctrl+K+FCTRL + SHIFT + B生成解决方案 Alt+B+B 或 F6 生成当 ...