使用QueueUserWorkerItem实现的线程池封装

时间:2022-09-03 15:20:10

此线程池所依赖的线程类,请参看《一个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&plus;&plus;封装编写线程池

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

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

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

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

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

随机推荐

  1. 阿里云服务器Linux CentOS安装配置(三)yum安装mysql

    阿里云服务器Linux CentOS安装配置(三)yum安装mysql 1.执行yum安装mysql命令:yum -y install mysql-server mysql-devel 2.启动mys ...

  2. 使用MySQL

    安装MySQL驱动 使用vpn $ pip install mysql-connector-python --allow-external mysql-connector-python import ...

  3. Windows Phone 8初学者开发—第21部分:永久保存Wav音频文件

    原文 Windows Phone 8初学者开发—第21部分:永久保存Wav音频文件 第21部分:永久保存Wav音频文件 原文地址:http://channel9.msdn.com/Series/Win ...

  4. 如何制定AxureRP设计体系

    经常有朋友问我,如何在从来没有用过AxureRP的公司或者团队里面开始使用AxureRP做原型设计?这个问题对个体来说不存在,因为个人学习使用AxureRP时非常快速的,基本试着做几个原型实例就能把整 ...

  5. JWT 多网站单点登录,放弃session

    多个网站之间的登录信息共享, 基于cookie - session的登录认证方式跨域等比较复杂.采用基于算法的认证方式, JWT(json web token)的方式. --------------- ...

  6. 浅谈 Java JPDA

    前言 程序员在坊间有非常多有趣的故事,其中就有这么一则:”这个在我的电脑上是好的,没问题的呀,诺,你看咯,一定是你打开姿势不正确,浏览器版本不正确,操作系统不统一等,总之不是我代码问题(傲娇)”.看到 ...

  7. macOS Sierra 10&period;12版本 显示隐藏文件

    1.显示隐藏文件 打开Terminal 输入:defaults write com.apple.finder AppleShowAllFiles -bool true 再输入: killall Fin ...

  8. jsp tomcat jdk版本对应

    jsp使用jdk8时,需要tomcat7以及以上版本,jsp在使用jdk7的时候,tomcat使用tomcat6即可

  9. Openflow Plugin学习笔记1

    主入口 ConfigurableOpenFlowProviderModule是OpenFlowPlugin中启动加载的入口,如下: @Override public java.lang.AutoClo ...

  10. Spring Bean 注入 2 注解篇

    1. 自动装配注解 配置applicationContext.xml开启注解 <?xml version="1.0" encoding="UTF-8"?& ...

相关文章