完整代码下载链接:
https://download.csdn.net/download/caozhiyuan930204/20418027
global.h
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
#include <functional>
typedef std::function<void()> BaseTask;
#endif
首先是线程池
ThreadPool.h
#pragma once
#include<list>
#include "global.h"
#include "CStack.h"
#include "CList.h"
#include"CQueue.h"
#include "Singletion.h"
#include <mutex>
class CThread;
enum PRIORITY
{
NORMAL,
HIGH
};
class CBaseThreadPool
{
public:
virtual bool SwitchActiveThread(CThread*)=0;
};
class CThreadPool :public CBaseThreadPool, public Singletion<CThreadPool>
{
friend class Singletion<CThreadPool>;
public:
CThreadPool();
~CThreadPool(void);
public:
virtual void CreateThreadPool(int num);
virtual CThread* PopIdleThread();
virtual bool SwitchActiveThread(CThread*);
virtual bool GetNewTask(BaseTask& task);
public:
//priority为优先级。高优先级的任务将被插入到队首。
bool addTask(BaseTask t, PRIORITY priority = NORMAL);
bool start();//开始调度。
bool destroyThreadPool();
private:
int m_nThreadNum;
bool m_bIsExit;
CStack m_IdleThreadStack;
CList m_ActiveThreadList;
CQueue m_TaskQueue;
};
主要包含 空闲线程栈,正在使用线程列表和任务队列
CStack m_IdleThreadStack;
CList m_ActiveThreadList;
CQueue m_TaskQueue;
这里的单例模式是采用继承通用的单例模板类,需要声明友元类不然无法访问私有的构造函数
friend class Singletion<CMyThreadPool>;
Singletion.h
#ifndef _SINGLEGION_H_
#define _SINGLEGION_H_
#include <mutex>
template<class T>
class Singletion
{
public:
static T* GetInstance()
{
std::lock_guard<std::mutex> lock(m_mutex);
if (NULL == m_pInstance)
{
m_pInstance = new T();
}
return m_pInstance;
};
static void ReleaseInstance()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
}
virtual ~Singletion(){}
protected:
Singletion(){}
private:
static T* m_pInstance;
static std::mutex m_mutex;
};
template<class T>
std::mutex Singletion<T>::m_mutex;
template<class T>
T* Singletion<T>::m_pInstance = NULL;
#endif
ThreadPool.cpp
#include "ThreadPool.h"
#include "CThread.h"
#include<cassert>
#include<iostream>
#include "CQueue.h"
#include "global.h"
CThreadPool::CThreadPool()
{
m_bIsExit=false;
}
CThreadPool::~CThreadPool(void)
{
}
void CThreadPool::CreateThreadPool(int num)
{
for (int i = 0; i<num; i++)
{
CThread*p = new CThread(this);
m_IdleThreadStack.push(p);
p->startThread();
}
}
CThread* CThreadPool::PopIdleThread()
{
CThread *pThread=m_IdleThreadStack.pop();
//pThread->m_bIsActive=true;
return pThread;
}
//将线程从活动队列取出,放入空闲线程栈中。在取之前判断此时任务队列是否有任务。如任务队列为空时才挂起。否则从任务队列取任务继续执行。
bool CThreadPool::SwitchActiveThread( CThread*t)
{
if(!m_TaskQueue.isEmpty())//任务队列不为空,继续取任务执行。
{
BaseTask task;
if (m_TaskQueue.pop(task))
{
std::cout << "线程:" << t->m_threadID << " 执行 ";// << pTask->getID() << std::endl;
t->assignTask(task);
t->startTask();
}
}
else//任务队列为空,该线程挂起。
{
m_ActiveThreadList.removeThread(t);
m_IdleThreadStack.push(t);
}
return true;
}
bool CThreadPool::addTask(BaseTask t, PRIORITY priority)
{
assert(t);
if(!t||m_bIsExit)
return false;
// std::cout<<" ["<<t->getID()<<"]添加!"<<std::endl;
if(priority==PRIORITY::NORMAL)
{
m_TaskQueue.push(t);//进入任务队列。
}
else if(PRIORITY::HIGH)
{
m_TaskQueue.pushFront(t);//高优先级任务。
}
if(!m_IdleThreadStack.isEmpty())//存在空闲线程。调用空闲线程处理任务。
{
BaseTask task;
if (!m_TaskQueue.pop(task))
{
std::cout << "任务取出出错。" << std::endl;
return false;
}
CThread*pThread=PopIdleThread();
// std::cout<<"【"<<pThread->m_threadID<<"】 执行 【"<<task->getID()<<"】"<<std::endl;
m_ActiveThreadList.addThread(pThread);
pThread->assignTask(task);
pThread->startTask();
}
return true;
}
bool CThreadPool::start()
{
return 0;
}
bool CThreadPool::GetNewTask(BaseTask& task)
{
if(m_TaskQueue.isEmpty())
{
return false;
}
m_TaskQueue.pop(task);//取出列头任务。
return true;
}
bool CThreadPool::destroyThreadPool()
{
m_bIsExit=true;
m_TaskQueue.clear();
m_IdleThreadStack.clear();
m_ActiveThreadList.clear();
return true;
}
CList
#pragma once
#include <list>
#include <mutex>
class CThread;
class CList
{
public:
CList(void);
~CList(void);
public:
bool addThread(CThread*t);
bool removeThread(CThread*t);
int getSize();
bool isEmpty();
bool clear();
private:
std::list<CThread*>m_list;
std::mutex m_mutex;
};
--------------------------------------------------
#include "CList.h"
#include <cassert>
#include"CThread.h"
CList::CList(void)
{
}
CList::~CList(void)
{
}
bool CList::addThread( CThread*t )
{
assert(t);
if(!t)
return false;
std::lock_guard<std::mutex> lock(m_mutex);
m_list.push_back(t);
return true;
}
bool CList::removeThread( CThread*t )
{
assert(t);
if(!t)
return false;
std::lock_guard<std::mutex> lock(m_mutex);
m_list.remove(t);
return true;
}
int CList::getSize()
{
std::lock_guard<std::mutex> lock(m_mutex);
int size= m_list.size();
return size;
}
bool CList::isEmpty()
{
std::lock_guard<std::mutex> lock(m_mutex);
bool ret= m_list.empty();
return ret;
}
bool CList::clear()
{
std::lock_guard<std::mutex> lock(m_mutex);
std::list<CThread*>::iterator iter=m_list.begin();
for(;iter!=m_list.end();iter++)
{
delete (*iter);
}
m_list.clear();
return true;
}
CQueue
#pragma once
#include<deque>
#include <mutex>
#include "global.h"
class CQueue
{
public:
CQueue(void);
~CQueue(void);
public:
bool pop(BaseTask& t);
//void pop();
bool push(const BaseTask& t);
bool pushFront(BaseTask& t);//插到队首。
bool isEmpty();
bool clear();
private:
std::deque<BaseTask>m_TaskQueue;
std::mutex m_mutex;
};
------------------------------------------------
#include "CQueue.h"
CQueue::CQueue(void)
{
}
CQueue::~CQueue(void)
{
}
bool CQueue::pop(BaseTask& p)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(!m_TaskQueue.empty())
{
p=m_TaskQueue.front();
m_TaskQueue.pop_front();
return true;
}
return false;
}
bool CQueue::push(const BaseTask& t)
{
if(!t)
{
return false;
}
std::lock_guard<std::mutex> lock(m_mutex);
m_TaskQueue.push_back(t);
return true;
}
bool CQueue::isEmpty()
{
bool ret=false;
std::lock_guard<std::mutex> lock(m_mutex);
ret=m_TaskQueue.empty();
return ret;
}
bool CQueue::pushFront(BaseTask& t)
{
if(!t)
{
return false;
}
std::lock_guard<std::mutex> lock(m_mutex);
m_TaskQueue.push_front(t);
return true;
}
bool CQueue::clear()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_TaskQueue.clear();
return true;
}
CStack
#pragma once
#include<stack>
#include <mutex>
class CThread ;
class CStack
{
public:
CStack(void);
~CStack(void);
public:
CThread* pop();
bool push(CThread*);
int getSize();
bool isEmpty();
bool clear();
private:
std::stack<CThread*> m_stack;
std::mutex m_mutex;
};
-------------------------------------------------------------
#include "CStack.h"
#include<cassert>
#include"CThread.h"
CStack::CStack(void)
{
}
CStack::~CStack(void)
{
}
CThread* CStack::pop()
{
std::lock_guard<std::mutex> lock(m_mutex);
if(!m_stack.empty())
{
CThread *t=m_stack.top();
m_stack.pop();
return t;
}
return NULL;
}
bool CStack::push( CThread* t)
{
assert(t);
if(!t)
return false;
std::lock_guard<std::mutex> lock(m_mutex);
m_stack.push(t);
return true;
}
int CStack::getSize()
{
std::lock_guard<std::mutex> lock(m_mutex);
int size= m_stack.size();
return size;
}
bool CStack::isEmpty()
{
std::lock_guard<std::mutex> lock(m_mutex);
bool ret= m_stack.empty();
return ret;
}
bool CStack::clear()
{
std::lock_guard<std::mutex> lock(m_mutex);
CThread*pThread=NULL;
while(!m_stack.empty())
{
pThread=m_stack.top();
m_stack.pop();
pThread->resumeThread();
pThread->m_bIsExit=true;
delete pThread;
}
return true;
}
CThread
#pragma once
#include "windows.h"
#include "global.h"
class CBaseThreadPool;
class CThread
{
public:
CThread(CBaseThreadPool*threadPool);
~CThread(void);
public:
bool startThread();
bool suspendThread();
bool resumeThread();
bool assignTask(BaseTask& pTask);
bool startTask();
static DWORD WINAPI threadProc(LPVOID pParam);
DWORD m_threadID;
HANDLE m_hThread;
bool m_bIsExit;
private:
HANDLE m_hEvent;
BaseTask m_pTask;
CBaseThreadPool*m_pThreadPool;
};
-------------------------------------------------------------
#include "CThread.h"
#include "ThreadPool.h"
#include<cassert>
#define WAIT_TIME 20
CThread::CThread(CBaseThreadPool*threadPool)
{
//m_bIsActive=false;
m_pThreadPool=threadPool;
m_hEvent=CreateEvent(NULL,false,false,NULL);
m_bIsExit=false;
}
//bool CThread::m_bIsActive=false;
CThread::~CThread(void)
{
CloseHandle(m_hEvent);
CloseHandle(m_hThread);
}
bool CThread::startThread()
{
m_hThread=CreateThread(0,0,threadProc,this,0,&m_threadID);
if(m_hThread==INVALID_HANDLE_VALUE)
{
return false;
}
return true;
}
bool CThread::suspendThread()
{
ResetEvent(m_hEvent);
return true;
}
//有任务到来,通知线程继续执行。
bool CThread::resumeThread()
{
SetEvent(m_hEvent);
return true;
}
DWORD WINAPI CThread::threadProc( LPVOID pParam )
{
CThread *pThread=(CThread*)pParam;
while(!pThread->m_bIsExit)
{
DWORD ret=WaitForSingleObject(pThread->m_hEvent,INFINITE);
if(ret==WAIT_OBJECT_0)
{
pThread->m_pTask();//执行任务。
pThread->m_pThreadPool->SwitchActiveThread(pThread);
}
}
return 0;
}
//将任务关联到线程类。
bool CThread::assignTask(BaseTask& pTask)
{
assert(pTask);
if(!pTask)
return false;
m_pTask=pTask;
return true;
}
//开始执行任务。
bool CThread::startTask()
{
resumeThread();
return true;
}
然后是使用,这里有两种使用方式,一种是全局函数,一种是类中静态函数作为任务
#include <iostream>
#include "ThreadPool.h"
#include "CThread.h"
#include "global.h"
static void add(int a, int b)
{
printf("%d + %d = %d\n", a, b, a + b);
return;
}
class TestTask
{
public:
TestTask();
~TestTask();
void PostAddTest(int a, int b);
void PostPrintTest(const std::string& strTest);
protected:
static void AddTest(void* pTask, int a, int b);
void HandleAddTest(int a, int b);
static void PrintTest(void* pTask, const std::string& strTest);
void HandlePrintTest(const std::string& strTest);
private:
};
TestTask::TestTask()
{
}
TestTask::~TestTask()
{
}
void TestTask::PostAddTest(int a, int b)
{
CThreadPool::GetInstance()->addTask(std::bind(&TestTask::AddTest, this, a, b));
}
void TestTask::AddTest(void* pTask, int a, int b)
{
TestTask* pTestTask = (TestTask*)pTask;
pTestTask->HandleAddTest(a, b);
}
void TestTask::HandleAddTest(int a, int b)
{
printf("a + b = %d\n", a + b);
}
void TestTask::PostPrintTest(const std::string& strTest)
{
CThreadPool::GetInstance()->addTask(std::bind(&TestTask::PrintTest, this, strTest));
}
void TestTask::PrintTest(void* pTask, const std::string& strTest)
{
TestTask* pTestTask = (TestTask*)pTask;
pTestTask->HandlePrintTest(strTest);
}
void TestTask::HandlePrintTest(const std::string& strTest)
{
printf("strTest = %s\n", strTest.c_str());
}
int main(int argc,char**argv)
{
CThreadPool::GetInstance()->CreateThreadPool(4);
//在类中使用
//TestTask testTask;
//for(int i=0;i<100;i++)
//{
// testTask.PostAddTest(i, i);
// testTask.PostPrintTest("hello");
//}
CThreadPool::GetInstance()->addTask(std::bind(&add, 4, 5));
//主线程执行其他工作。
{
Sleep(1000*1000);
}
CThreadPool::GetInstance()->destroyThreadPool();
CThreadPool::ReleaseInstance();
return 0;
}
完整代码下载链接
https://download.csdn.net/download/caozhiyuan930204/20418027