原文转自:http://www.cnblogs.com/lidabo/p/3328646.html

略有修改

Cthread类参见:http://www.cnblogs.com/tangxin-blog/p/4835211.html

CThreadPool.h

 #ifndef __MY_THREAD_POOL_H_
#define __MY_THREAD_POOL_H_ #include "CThread.h"
#include <set>
#include <list>
#include <windows.h>
using namespace std; class CThreadPool
{
public:
CThreadPool(void);
virtual ~CThreadPool(void);
// 初始化线程池,创建minThreads个线程
bool Initialize(unsigned int minThreadCnt,unsigned int maxThreadCnt,unsigned int maxTaskQueueLength);
bool AddTask( CRunnable *pRunnable, bool bRun = true);
void Terminate();
// 获取线程数量
unsigned int GetThreadCnt();
private:
// 从任务队列头中取出一个任务
CRunnable *GetTask();
// 执行任务线程
static unsigned int WINAPI StaticThreadFunc(void * arg);
private:
// 工作者类
class CWorker : public CThread
{
public:
CWorker(CThreadPool *pThreadPool,CRunnable *pFirstTask = NULL);
~CWorker();
void Run();
private:
CThreadPool * const m_pThreadPool;
CRunnable * const m_pFirstTask;
volatile bool m_bRun;
}; typedef std::set<CWorker *> ThreadPool;
typedef std::list<CRunnable *> Tasks;
typedef Tasks::iterator TasksItr;
typedef ThreadPool::iterator ThreadPoolItr; CRITICAL_SECTION m_csTasksLock;
CRITICAL_SECTION m_csThreadPoolLock; // 线程池
ThreadPool m_ThreadPool;
// 垃圾线程
ThreadPool m_TrashThread;
// 任务队列
Tasks m_Tasks;
// 是否在运行
volatile bool m_bRun;
// 能否插入任务
volatile bool m_bEnableInsertTask;
// 最小线程数
volatile unsigned int m_minThreads;
// 最大线程数
volatile unsigned int m_maxThreads;
// 最大挂起任务数量
volatile unsigned int m_maxPendingTasks;
}; #endif

CthreadPool.cpp

#include "CThreadPool.h"

CThreadPool::CWorker::CWorker(CThreadPool *pThreadPool,CRunnable *pFirstTask)
:m_pThreadPool(pThreadPool),m_pFirstTask(pFirstTask),m_bRun(true)
{ } CThreadPool::CWorker::~CWorker()
{
} void CThreadPool::CWorker::Run()
{
CRunnable * pTask = NULL;
while(m_bRun)
{
// 从线程池的任务队列中取出一个任务
pTask = m_pThreadPool->GetTask();
// 如果没有取到任务
if(NULL == pTask)
{
EnterCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
// 如果运转的线程数大于最小线程数,需要清除多余的线程
if(m_pThreadPool->GetThreadCnt() > 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;
}
}
} CThreadPool::CThreadPool(void):m_bRun(false),m_bEnableInsertTask(false)
{
InitializeCriticalSection(&m_csTasksLock);
InitializeCriticalSection(&m_csThreadPoolLock);
} CThreadPool::~CThreadPool(void)
{
Terminate();
DeleteCriticalSection(&m_csTasksLock);
DeleteCriticalSection(&m_csThreadPoolLock);
} bool CThreadPool::Initialize(unsigned int minThreadCnt,unsigned int maxThreadCnt,unsigned int maxTaskQueueLength)
{
if(minThreadCnt == )
{
return false;
}
if(minThreadCnt > maxThreadCnt)
{
return false;
}
m_minThreads = minThreadCnt;
m_maxThreads = maxThreadCnt;
m_maxPendingTasks = maxTaskQueueLength;
unsigned int i = m_ThreadPool.size();
for(; i<minThreadCnt; i++)
{
//创建线程 minThreadCnt 个线程
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;
} unsigned int CThreadPool::GetThreadCnt()
{
return m_ThreadPool.size();
} CRunnable * CThreadPool::GetTask()
{
CRunnable *Task = NULL;
EnterCriticalSection(&m_csTasksLock);
if(!m_Tasks.empty())
{
Task = m_Tasks.front();
m_Tasks.pop_front();
}
LeaveCriticalSection(&m_csTasksLock);
return Task;
} bool CThreadPool::AddTask( CRunnable *pRunnable, bool bRun /*= true*/ )
{
if(m_bEnableInsertTask == false)
{
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;
} void CThreadPool::Terminate()
{
m_bEnableInsertTask = false;
while(m_Tasks.size() > )
{
Sleep();
}
m_bRun = false;
m_minThreads = ;
m_maxThreads = ;
m_maxPendingTasks = ;
while(m_ThreadPool.size() > )
{
Sleep();
}
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 <iostream>
#include <windows.h>
#include <time.h>
#include "CThread.h"
#include "CThreadPool.h"
using namespace std; class R : public CRunnable
{
public:
R(int t):m_nt(t)
{
}
~R()
{
cout<<"~R:"<<m_nt<<endl;
}
void Run()
{
Sleep(m_nt);
}
int m_nt;
}; int main()
{
int i,n = ,m;
time_t start = ,end = ;
R r();
/*
// 单线程
start = clock();
for(i=0;i < n;i++)
{
r.Run();
}
end = clock();
cout<<"单线程用时:"<<end - start<<endl;
*/
// 多线程
start = clock();
CThread *ths = NULL;
ths = new CThread[n];
for(i=;i < n;i++)
{
ths[i].SetRunnable(&r);
ths[i].Start();
}
for(i=;i < n;i++)
{
ths[i].Join();
}
delete[] ths;
end = clock();
cout<<"多线程用时:"<<end - start<<endl;
// 线程池
start = clock();
CThreadPool *threadPool = new CThreadPool();
if(threadPool->Initialize(,,) == false)
{
cout<<"Initialize failed"<<endl;
return -;
}
m = ;
for(int i=;i<n;i++)
{
if( !threadPool->AddTask(&r) )
{
m++;
}
}
threadPool->Terminate();
delete threadPool;
end = clock();
if(m!=)
{
cout<<m<<endl;
}
cout<<"线程池用时:"<<end - start<<endl;
system("pause");
return ;
}

注意:要合理设置最小线程数,最大线程数,最大挂起任务数量,以便达到最优性能。

转载:C++线程池的一个实现的更多相关文章

  1. [转载] Java线程池框架源码分析

    转载自http://www.linuxidc.com/Linux/2014-11/108791.htm 相关类Executor,Executors,AbstractExecutorService,Ex ...

  2. ThreadPoolExecutor线程池的一个面试题

    问题:现有一个线程池,参数corePoolSize = 5,maximumPoolSize = 10,BlockingQueue阻塞队列长度为5,此时有4个任务同时进来,问:线程池会创建几条线程? 如 ...

  3. 【转】一个windows线程池实现

    #ifndef _ThreadPool_H_ #define _ThreadPool_H_ #pragma warning(disable: 4530) #pragma warning(disable ...

  4. Java并发编程:线程池的使用(转载)

    转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  5. Java并发编程:线程池的使用(转载)

    文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  6. Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程

    下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...

  7. 深入了解java线程池(转载)

    出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责 ...

  8. 分享一个自制的 .net线程池

    扯淡 由于项目需求,需要开发一些程序去爬取一些网站的信息,算是小爬虫程序吧.爬网页这东西是要经过网络传输,如果程序运行起来串行执行请求爬取,会很慢,我想没人会这样做.为了提高爬取效率,必须使用多线程并 ...

  9. asp.net core C#设计一个实用的线程池

    菜菜呀,我最近研究技术呢,发现线上一个任务程序线程数有点多呀 CEO,CTO,CFO于一身的CXO x总,你学编程呢? 菜菜 作为公司总负责人,我以后还要管理技术部门呢,怎么能不会技术呢 CEO,CT ...

随机推荐

  1. Xamarin iOS编写第一个应用程序创建工程

    Xamarin iOS编写第一个应用程序创建工程 在Xcode以及Xamarin安装好后,就可以在Xamarin Studio中编写程序了.本节将主要讲解在Xamarin Studio中如何进行工程的 ...

  2. 在JavaScript中,this关键字指什么?

    指向对象.window.方法. 例子1 function a(){//当前调用栈是a,因此a的调用位置是全局作用域 console.log('a'); b();// b的调用位置 } function ...

  3. 递推DP URAL 1119 Metro

    题目传送门 /* 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 递推DP:仿照JayYe,处理的很巧妙,学习:) 好 ...

  4. 模拟 POJ 1068 Parencodings

    题目地址:http://poj.org/problem?id=1068 /* 题意:给出每个右括号前的左括号总数(P序列),输出每对括号里的(包括自身)右括号总数(W序列) 模拟题:无算法,s数组把左 ...

  5. LightOJ1119 Pimp My Ride(状压DP)

    dp[S]表示已经完成的工作集合 枚举从哪儿转移过来的,再通过枚举计算花费..水水的.. #include<cstdio> #include<cstring> #include ...

  6. A C[HDU1570]

    A C Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  7. quick cocos map使用

    '''lua local MainScene = class("MainScene", function() return display.newScene("MainS ...

  8. ZOJ 3805 (树形DP)

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5337 题目大意:方块连接,呈树形.每个方块有两种接法,一种接在父块 ...

  9. POJ 3335 Rotating Scoreboard(多边形的核)

    题目链接 我看的这里:http://www.cnblogs.com/ka200812/archive/2012/01/20/2328316.html 然后整理一下当做模版.0换成eps,会wa,应该要 ...

  10. UiAutomator 测试工程开发小结

    一.    关于bundle无法导入中文参数 答:    将文件改为UTF-8格式 二.    关于对无法抓取的控件进行快速输入问题 答:    主要通过pressKeyCode方法,首先将光标锁定在 ...