线程池-std::function作为通用的任务

完整代码下载链接:

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值