原文转自: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. 分享Kali Linux 2016.2第36周镜像虚拟机

    分享Kali Linux 2016.2第36周镜像虚拟机   9月9日,Kali Linux官方发布Kali Linux 2016.2周更新镜像.今天以64位镜像安装了一个虚拟机,分享给大家.该虚拟机 ...

  2. JAVA定时执行任务,每天定时几点钟执行任务

    JAVA定时执行任务,每天定时几点钟执行任务的示例如下: 1.建立TimerManage类,设置时间点,时间点设置的管理类,代码如下: package com.pcitc.time; import j ...

  3. DataMember IsRequired属性

        1.简介 在数据契约中,如果需要序列化时,则需要传入指定IsRequired属性:   摘要: 获取或设置一个值,该值用于指示序列化引擎在读取或反序列化时成员必须存在.   public bo ...

  4. HDU2841 Visible Trees(容斥原理)

    题目..大概就是有个m*n个点的矩形从(1,1)到(m,n),问从(0,0)出发直线看过去最多能看到几个点. 如果(0,0)->(x,y)和(0,0)->(x',y')两个向量平行,那后面 ...

  5. ural 1272. Non-Yekaterinburg Subway

    1272. Non-Yekaterinburg Subway Time limit: 1.0 secondMemory limit: 64 MB A little town started to co ...

  6. Rain on your Parade

    Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Java/Ot ...

  7. storm Tutorial 的解读 + 个人理解

    参考链接: Tutorial storm Tutorial 中文解读+分析 导读.摘要: .hadoop有master与slave,Storm与之对应的节点是什么? .Storm控制节点上面运行一个后 ...

  8. 我理解的 js 的观察者模式 Observable

    我第一次看 四人帮 写的<设计模式>时一头雾水,现在也是,或许其是针对专业的程序员学习使用的. 通过对Ext / Backbone 源码的学习,可总结如下: 模式 - 就是对解决某一类特定 ...

  9. 转载 模板整理 by gc812

    http://www.cnblogs.com/gc812/p/5779789.html 上友链,不盗版 CC BY-NC-SA

  10. jsoncpp代码实例

    最近开始使用 jsoncpp,以前一直在使用cJSON,但是使用cJSON的时候经常会忘记free掉json的内存,结果造成了内存泄露,程序跑着跑着就崩溃了.所以最近把json转移到了jsoncpp上 ...