一个Windows C++的线程池的实现
此线程池所依赖的线程类,请参看《一个Windows C++的线程类实现》:
http://blog.csdn.net/huyiyang2010/archive/2010/08/10/5801597.aspx
ThreadPoolExecutor.h
- #ifndef __THREAD_POOL_EXECUTOR__
- #define __THREAD_POOL_EXECUTOR__
- #include "Thread.h"
- #include <set>
- #include <list>
- #include <windows.h>
- class CThreadPoolExecutor
- {
- public:
- CThreadPoolExecutor(void);
- ~CThreadPoolExecutor(void);
- /**
- 初始化线程池,创建minThreads个线程
- **/
- bool Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTaskse);
- /**
- 执行任务,若当前任务列表没有满,将此任务插入到任务列表,返回true
- 若当前任务列表满了,但当前线程数量小于最大线程数,将创建新线程执行此任务,返回true
- 若当前任务列表满了,但当前线程数量等于最大线程数,将丢弃此任务,返回false
- **/
- bool Execute(Runnable * pRunnable);
- /**
- 终止线程池,先制止塞入任务,
- 然后等待直到任务列表为空,
- 然后设置最小线程数量为0,
- 等待直到线程数量为空,
- 清空垃圾堆中的任务
- **/
- void Terminate();
- /**
- 返回线程池中当前的线程数量
- **/
- unsigned int GetThreadPoolSize();
- private:
- /**
- 获取任务列表中的任务,若任务列表为空,返回NULL
- **/
- Runnable * GetTask();
- static unsigned int WINAPI StaticThreadFunc(void * arg);
- private:
- class CWorker : public CThread
- {
- public:
- CWorker(CThreadPoolExecutor * pThreadPool, Runnable * pFirstTask = NULL);
- ~CWorker();
- void Run();
- private:
- CThreadPoolExecutor * m_pThreadPool;
- Runnable * m_pFirstTask;
- volatile bool m_bRun;
- };
- typedef std::set<CWorker *> ThreadPool;
- typedef std::list<Runnable *> Tasks;
- typedef Tasks::iterator TasksItr;
- typedef ThreadPool::iterator ThreadPoolItr;
- ThreadPool m_ThreadPool;
- ThreadPool m_TrashThread;
- Tasks m_Tasks;
- CRITICAL_SECTION m_csTasksLock;
- CRITICAL_SECTION m_csThreadPoolLock;
- volatile bool m_bRun;
- volatile bool m_bEnableInsertTask;
- volatile unsigned int m_minThreads;
- volatile unsigned int m_maxThreads;
- volatile unsigned int m_maxPendingTasks;
- };
- #endif
ThreadPoolExecutor.cpp
- #include "ThreadPoolExecutor.h"
- CThreadPoolExecutor::CWorker::CWorker(CThreadPoolExecutor * pThreadPool, Runnable * pFirstTask) :
- m_pThreadPool(pThreadPool),
- m_pFirstTask(pFirstTask),
- m_bRun(true)
- {
- }
- CThreadPoolExecutor::CWorker::~CWorker()
- {
- }
- /**
- 执行任务的工作线程。
- 当前没有任务时,
- 如果当前线程数量大于最小线程数量,减少线程,
- 否则,执行清理程序,将线程类给释放掉
- **/
- void CThreadPoolExecutor::CWorker::Run()
- {
- Runnable * pTask = NULL;
- while(m_bRun)
- {
- if(NULL == m_pFirstTask)
- {
- pTask = m_pThreadPool->GetTask();
- }
- else
- {
- pTask = m_pFirstTask;
- m_pFirstTask = NULL;
- }
- if(NULL == pTask)
- {
- EnterCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
- if(m_pThreadPool->GetThreadPoolSize() > m_pThreadPool->m_minThreads)
- {
- ThreadPoolItr itr = m_pThreadPool->m_ThreadPool.find(this);
- if(itr != m_pThreadPool->m_ThreadPool.end())
- {
- m_pThreadPool->m_ThreadPool.erase(itr);
- m_pThreadPool->m_TrashThread.insert(this);
- }
- m_bRun = false;
- }
- else
- {
- ThreadPoolItr itr = m_pThreadPool->m_TrashThread.begin();
- while(itr != m_pThreadPool->m_TrashThread.end())
- {
- (*itr)->Join();
- delete (*itr);
- m_pThreadPool->m_TrashThread.erase(itr);
- itr = m_pThreadPool->m_TrashThread.begin();
- }
- }
- LeaveCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
- continue;
- }
- else
- {
- pTask->Run();
- pTask = NULL;
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- CThreadPoolExecutor::CThreadPoolExecutor(void) :
- m_bRun(false),
- m_bEnableInsertTask(false)
- {
- InitializeCriticalSection(&m_csTasksLock);
- InitializeCriticalSection(&m_csThreadPoolLock);
- }
- CThreadPoolExecutor::~CThreadPoolExecutor(void)
- {
- Terminate();
- DeleteCriticalSection(&m_csTasksLock);
- DeleteCriticalSection(&m_csThreadPoolLock);
- }
- bool CThreadPoolExecutor::Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTasks)
- {
- if(minThreads == 0)
- {
- return false;
- }
- if(maxThreads < minThreads)
- {
- return false;
- }
- m_minThreads = minThreads;
- m_maxThreads = maxThreads;
- m_maxPendingTasks = maxPendingTasks;
- unsigned int i = m_ThreadPool.size();
- for(; i<minThreads; i++)
- {
- //创建线程
- CWorker * pWorker = new CWorker(this);
- if(NULL == pWorker)
- {
- return false;
- }
- EnterCriticalSection(&m_csThreadPoolLock);
- m_ThreadPool.insert(pWorker);
- LeaveCriticalSection(&m_csThreadPoolLock);
- pWorker->Start();
- }
- m_bRun = true;
- m_bEnableInsertTask = true;
- return true;
- }
- bool CThreadPoolExecutor::Execute(Runnable * pRunnable)
- {
- if(!m_bEnableInsertTask)
- {
- return false;
- }
- if(NULL == pRunnable)
- {
- return false;
- }
- if(m_Tasks.size() >= m_maxPendingTasks)
- {
- if(m_ThreadPool.size() < m_maxThreads)
- {
- CWorker * pWorker = new CWorker(this, pRunnable);
- if(NULL == pWorker)
- {
- return false;
- }
- EnterCriticalSection(&m_csThreadPoolLock);
- m_ThreadPool.insert(pWorker);
- LeaveCriticalSection(&m_csThreadPoolLock);
- pWorker->Start();
- }
- else
- {
- return false;
- }
- }
- else
- {
- EnterCriticalSection(&m_csTasksLock);
- m_Tasks.push_back(pRunnable);
- LeaveCriticalSection(&m_csTasksLock);
- }
- return true;
- }
- Runnable * CThreadPoolExecutor::GetTask()
- {
- Runnable * Task = NULL;
- EnterCriticalSection(&m_csTasksLock);
- if(!m_Tasks.empty())
- {
- Task = m_Tasks.front();
- m_Tasks.pop_front();
- }
- LeaveCriticalSection(&m_csTasksLock);
- return Task;
- }
- unsigned int CThreadPoolExecutor::GetThreadPoolSize()
- {
- return m_ThreadPool.size();
- }
- void CThreadPoolExecutor::Terminate()
- {
- m_bEnableInsertTask = false;
- while(m_Tasks.size() > 0)
- {
- Sleep(1);
- }
- m_bRun = false;
- m_minThreads = 0;
- m_maxThreads = 0;
- m_maxPendingTasks = 0;
- while(m_ThreadPool.size() > 0)
- {
- Sleep(1);
- }
- EnterCriticalSection(&m_csThreadPoolLock);
- ThreadPoolItr itr = m_TrashThread.begin();
- while(itr != m_TrashThread.end())
- {
- (*itr)->Join();
- delete (*itr);
- m_TrashThread.erase(itr);
- itr = m_TrashThread.begin();
- }
- LeaveCriticalSection(&m_csThreadPoolLock);
- }
用法:
#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++的线程池的实现的更多相关文章
- 分享一个自制的 .net线程池
扯淡 由于项目需求,需要开发一些程序去爬取一些网站的信息,算是小爬虫程序吧.爬网页这东西是要经过网络传输,如果程序运行起来串行执行请求爬取,会很慢,我想没人会这样做.为了提高爬取效率,必须使用多线程并 ...
- windows下利用线程池完成多任务的分配和运行
在做项目的过程中有时候为了提升效率,用了多线程的方法来对任务进行分割和应用,后来发现,采用线程池的方法能更好的利用线程资源来计算任务,网上有很多关于如何运行线程池的例子,msdn上也给出了对应的例子: ...
- 一个简单的python线程池框架
初学python,实现了一个简单的线程池框架,线程池中除Wokers(工作线程)外,还单独创建了一个日志线程,用于日志的输出.线程间采用Queue方式进行通信. 代码如下:(不足之处,还请高手指正) ...
- 一个简单的linux线程池(转-wangchenxicool)
线程池:简单地说,线程池 就是预先创建好一批线程,方便.快速地处理收到的业务.比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高. 在linux中,使用的 ...
- 一个Linux下C线程池的实现
什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了.如果线程创建和销毁时间相比任 ...
- 一个boost底下的线程池
Boost的thread库中目前并没有提供线程池,我在sorceforge上找了一个用boost编写的线程池.该线程池和boost结合的比较好,并且提供了多种任务执行策略,使用也非常简单. 下载地址: ...
- 一个Work Stealing Pool线程池的实现
一.一般来说实现一个线程池主要包括以下几个组成部分: 1)线程管理器 :用于创建并管理线程池 . 2)工作线程 :线程池中实际执行任务的线程 . 在初始化线程时会预先创建好固定数目的线程在池中 ,这些 ...
- Windows下一个比较完美的线程池实现(使用线程池实现的Http上传下载实现)
http://blog.csdn.net/fishjam/article/details/8632049 http://download.csdn.net/user/fishjam
- 一个Windows C++的线程类实现
Thread.h [cpp] view plaincopy #ifndef __THREAD_H__ #define __THREAD_H__ #include <string> #inc ...
随机推荐
- java学习:AWT组件和事件处理的笔记(1)--菜单条,菜单,菜单项
菜单放在菜单条里,菜单项放在菜单里1.MenuBar 在java.awt包中,负责创建菜单条,即MenuBar的一个实例,便是一个菜单条. 在Frame类中的setMenuBar(Menu ...
- 【原创】QT5-卸载精灵v1.0-卸载windows软件-简易版
由于项目需求,需要实现卸载windows上的普通软件的小功能,实现起来还是比较简单的. 先发个图: 思路: 1.根据注册表的信息去打开应用程序,卸载也一样: 2.读桌面的快捷方式,根据快捷方式的指向路 ...
- Nginx安装配置PHP(FastCGI)环境的教程
这篇是Nginx安装配置PHP(FastCGI)环境的教程.Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用. 一.什么是 FastCGI F ...
- 解决:getWeatherbyCityName(city),服务器无法处理请求。 ---> 未将对象引用设置到对象的实例。
原文:getWeatherbyCityName(city),服务器无法处理请求. ---> 未将对象引用设置到对象的实例. 解决方法:不要直接使用 “服务引用” , 添加为 “Web 引用” 最 ...
- session_cache_limiter 及 session 常见问题
我点击后退按钮,为什么之前填写的东西不见 这是因为你使用了session. 解决办法: PHP代码:-------------------------------------------------- ...
- 线上操作使用tmux提高工作效率
对于常常在线上操作的人来说有一种烦恼,就是在操作过程中,有事离开了一下,电脑自己主动睡眠了.然后网络断开连接.这时候任务就要又一次跑.非常烦恼. tmux能够解决问题. tmux能够看成虚拟屏幕,不受 ...
- 实现在Android 多点手势识别
google 提供的API中,有个类,大家都很熟悉,GestureDetector.使用它,我们可以识别用户通常会用的手势.但是,这个类不支持多点触摸(可能 google认为没有人会在几个手指都在屏幕 ...
- Java Math的 floor,round和ceil的总结
floor 返回不大于的最大整数 round 则是4舍5入的计算,入的时候是到大于它的整数round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下 ...
- php之Cookie与Session详解
Cookie管理 Cookie是在HTTP协议下,通过服务器或脚本语言可以维护客户浏览器上信息的一种方式,Cookie的使用很普遍,许多提供个人化服务的网站都是利用Cookie来区别不同用户,以显示与 ...
- asp.net 跨页面传值常用方法
常用方法有以下: 1.queryString 2.form-post控件传递 3.cookie 4.application 5.session querystring: http://website. ...