使用QueueUserWorkerItem实现的线程池封装
此线程池所依赖的线程类,请参看《一个Windows C++的线程类实现》:
http://blog.csdn.net/huyiyang2010/archive/2010/08/10/5801597.aspx
SystemThreadPool.h
- #define __SYSTEM_THREAD_POOL__
- #include "Thread.h"
- #include <list>
- #include <windows.h>
- class CThreadPoolExecutor
- {
- public:
- CThreadPoolExecutor(void);
- ~CThreadPoolExecutor(void);
- /**
- 初始化线程池,创建minThreads个线程
- **/
- bool Init(unsigned int maxTaskse);
- /**
- 执行任务,若当前任务列表没有满,将此任务插入到任务列表,返回true
- 否则返回false
- **/
- bool Execute(Runnable * pRunnable);
- /**
- 终止线程池,先制止塞入任务,
- 然后等待直到任务列表为空,
- 然后设置最小线程数量为0,
- 等待直到线程数量为空,
- 清空垃圾堆中的任务
- **/
- void Terminate();
- /**
- 返回线程池中当前的线程数量
- **/
- unsigned int GetThreadPoolSize();
- private:
- static unsigned int WINAPI StaticThreadFunc(void * arg);
- private:
- typedef std::list<Runnable *> Tasks;
- typedef Tasks::iterator TasksItr;
- Tasks m_Tasks;
- CRITICAL_SECTION m_csTasksLock;
- volatile bool m_bRun;
- volatile bool m_bEnableInsertTask;
- volatile unsigned int m_maxTasks;
- };
- #endif
SytemThreadPool.cpp
- #include "SystemThreadPool.h"
- CThreadPoolExecutor::CThreadPoolExecutor(void) :
- m_bRun(false),
- m_bEnableInsertTask(false)
- {
- InitializeCriticalSection(&m_csTasksLock);
- }
- CThreadPoolExecutor::~CThreadPoolExecutor(void)
- {
- Terminate();
- DeleteCriticalSection(&m_csTasksLock);
- }
- bool CThreadPoolExecutor::Init(unsigned int maxTasks)
- {
- if(maxTasks == 0)
- {
- return false;
- }
- m_maxTasks = maxTasks;
- m_bRun = true;
- m_bEnableInsertTask = true;
- return true;
- }
- bool CThreadPoolExecutor::Execute(Runnable * pRunnable)
- {
- if(!m_bEnableInsertTask)
- {
- return false;
- }
- if(NULL == pRunnable)
- {
- return false;
- }
- EnterCriticalSection(&m_csTasksLock);
- if(m_Tasks.size() >= m_maxTasks)
- {
- LeaveCriticalSection(&m_csTasksLock);
- return false;
- }
- m_Tasks.push_back(pRunnable);
- LeaveCriticalSection(&m_csTasksLock);
- bool ret = QueueUserWorkItem((LPTHREAD_START_ROUTINE)StaticThreadFunc, this, WT_EXECUTEINPERSISTENTIOTHREAD);
- if(!ret)
- {
- EnterCriticalSection(&m_csTasksLock);
- m_Tasks.remove(pRunnable);
- LeaveCriticalSection(&m_csTasksLock);
- }
- return ret;
- }
- unsigned int CThreadPoolExecutor::GetThreadPoolSize()
- {
- return m_Tasks.size();
- }
- void CThreadPoolExecutor::Terminate()
- {
- m_bEnableInsertTask = false;
- m_bRun = false;
- while(m_Tasks.size() != 0)
- {
- Sleep(1);
- }
- }
- unsigned int WINAPI CThreadPoolExecutor::StaticThreadFunc(void * arg)
- {
- CThreadPoolExecutor * pThreadPool = (CThreadPoolExecutor *)arg;
- Runnable * pRunnable = NULL;
- EnterCriticalSection(&pThreadPool->m_csTasksLock);
- pRunnable = pThreadPool->m_Tasks.front();
- if(NULL != pRunnable)
- {
- pThreadPool->m_Tasks.pop_front();
- }
- LeaveCriticalSection(&pThreadPool->m_csTasksLock);
- if(NULL != pRunnable)
- {
- pRunnable->Run();
- }
- return 0;
- }
用法:
#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实现的线程池封装的更多相关文章
- jedis使用线程池封装redis基本操作
redisclient jedis 经常使用的 操作 key value hash list set zset 的基本操作 package cn.zto.util; import java.util. ...
- Java开发笔记(一百零四)普通线程池的运用
前面介绍了线程的基本用法,以及多线程并发的问题处理,但实际开发中往往存在许多性质相似的任务,比如批量发送消息.批量下载文件.批量进行交易等等.这些同类任务的处理流程一致,不存在资源共享问题,相互之间也 ...
- Java ExecutorService四种线程池及自定义ThreadPoolExecutor机制
一.Java 线程池 Java通过Executors提供四种线程池,分别为:1.newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收 ...
- 谈谈Java的线程池设计
在实际项目中,如果因为想异步执行暂时性的任务而不断创建线程是很浪费资源的事情(当一个任务执行完后,线程也没用了).这种情况下,最好是将任务提交给线程池执行. 所谓池,就是将管理某一种资源,对资源进行复 ...
- 进程池与线程池基本使用、协程理论与实操、IO模型、前端、BS架构、HTTP协议与HTML前戏
昨日内容回顾 GIL全局解释器锁 1.在python解释器中 才有GIL的存在(只与解释器有关) 2.GIL本质上其实也是一把互斥锁(并发变串行 牺牲效率保证安全) 3.GIL的存在 是由于Cpyth ...
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
- c++封装编写线程池
在csapp学习或者其他linux底层编程的过程中,一般都会举一些多线程或多进程的例子,配合底层同步原语.系统调用api来解释怎么创建多线程/多进程. 但是这些例子和实际项目中所用到的多线程/多进程编 ...
- 面向对象的线程池Threadpool的封装
线程池是一种多线程处理形式,预先创建好一定数量的线程,将其保存于一个容器中(如vector), 处理过程中将任务添加到队列,然后从容器中取出线程后自动启动这些任务,具体实现如下. 以下是UML图,展示 ...
- 线程池、及使用场景、线程安全封装、ConcurrentHashMap应用场景
https://blog.csdn.net/sinbadfreedom/article/details/80467253 :1.HashMap与ConcurrentHashMap的区别与应用场景 h ...
随机推荐
- GitHub问题之恢复本地被删除的文件
折腾了真久,GitHub commit之后,我手痒把本地的一个文件给删了,然后一直Git pull都发现不能恢复.远程库里面还是有该文件的.就是我想将远程库的文件回到本地被删除了的位置. 特别的是,我 ...
- u Calculate e
问题陈述: 杭州电子科技大学 HANGZHOU DIANZI UNIVERSITY Online Judge Problem - 1012 问题解析: 简单题,注意输出格式.引入<iomaini ...
- Git 操作常用命令
Git使用 1. git pull 更新服务器代码到本地a). git pull origin master是将origin这个版本库的代码更新到本地的master主分支 2. git push ...
- Oracle EBS-SQL (WIP-6):检查任务已完成但状态是发放的任务.sql
select WE.WIP_ENTITY_NAME ,MSI.SEGMENT1 ,MSI.DESCRIPTION ,WDJ.CLASS_CODE ...
- jdk7和8的一些新特性介绍
jdk7和8的一些新特性介绍 本文是我学习了解了jdk7和jdk8的一些新特性的一些资料,有兴趣的大家可以浏览下下面的内容. 官方文档:http://www.oracle.com/technetwor ...
- Final Exam Arrangement(ZOJ)
In Zhejiang University, there are N different courses labeled from 1 to N. Each course has its own t ...
- MGTemplateEngine 模版引擎简单使用(转)
原文:http://blog.csdn.net/crazy_srufboy/article/details/21748995 要实现的效果 首先上图中间的 标题至内容 都是使用UIWebView显示, ...
- 佩特来项目经验小集合(2)___组合查询存储过程,报错 "varchar JBID='' 转换成数据类型 int 时失败"
今天写一个组合查询的存储过程遇到这样一个问题:在将 varchar 值 'SELECT * FROM View_DLS_WXJD_Customer WHERE 1=1 and JBID ='' ...
- Docker简单介绍
Docker简单介绍 Docker是一个能够把开发的应用程序非常方便地部署到容器的开源引擎.由Docker公司团队编写,基于Apache 2.0开源授权协议发行.Docker的主要目的例如以下: 提供 ...
- oracle update语句的几点写法
update两表关联的写法包括字查询 1.update t2 set parentid=(select ownerid from t1 where t1.id=t2.id); 2. update tb ...