C++线程池的实现

//MySelfThread.h头文件
//MySelfThread.h头文件
#ifndef MYSELFTHREAD_H
#define MYSELFTHREAD_H
#include <thread>
#include <condition_variable>
#include <mutex>
#include <vector>
typedef struct
{
	void *pThat;
	std::condition_variable condit;
	std::mutex mtx;
	std::function<void(void*)> handleFunc;
	void *funcParam;
}ThreadItem;

class MySelfThread
{
public:
	MySelfThread();

	~MySelfThread();

	void SetIsRunning(bool is) { g_isRunning = is; }

	bool GetIsRunning(){ return g_isRunning; }

	void Start();

	void ActiveRsk(std::function<void(void*)> func, void *param);

	void Realse();

	void CreateThreadItem(std::function<void(void*)> func, void *param);

private:
	void UpdateRsk(std::function<void(void*)> func, void *param);

private:
	bool g_isRunning;

	ThreadItem *m_threadItem;
	std::mutex m_mtx;
};

#endif

//MySelfThread.cpp
#include "MySelfThread.h"
#include "ThreadPool.h"
#include <iostream>
MySelfThread::MySelfThread() :m_threadItem(nullptr)
{
	g_isRunning = true;
}


MySelfThread::~MySelfThread()
{
	g_isRunning = false;
}

void ThreadRun(ThreadItem *pItem)
{
	MySelfThread *pThis = (MySelfThread*)pItem->pThat;
	if (NULL == pThis)
	{
		return;
	}
	while (pThis->GetIsRunning())
	{
		std::unique_lock<std::mutex> lx(pItem->mtx);
		/*避免虚假唤醒*/
		while (nullptr == pItem->handleFunc)
		{
			pItem->condit.wait(lx);
		}

		if (pItem->handleFunc)
		{
			pItem->handleFunc(pItem->funcParam);
			pThis->Realse();
		}

	}
}

void MySelfThread::Start()
{
	std::thread th1(ThreadRun, m_threadItem);
	th1.detach();
}

void MySelfThread::ActiveRsk(std::function<void(void*)> func, void *param)
{
	std::lock_guard<std::mutex> lmx(m_mtx);
	UpdateRsk(func, param);
	m_threadItem->condit.notify_one();//用notify_one()如果不加条件while (nullptr == pItem->handleFunc),linux下唤不醒,window没问题,如果不加条件的话用notify_all()
}

void MySelfThread::Realse()
{
	std::lock_guard<std::mutex> lmx(m_mtx);
	UpdateRsk(nullptr, nullptr);
	/*从工作移到空闲,方便后续使用*/
	ThreadPool::GetInstance()->RealseTsk(this);
}

void MySelfThread::UpdateRsk(std::function<void(void*)> func, void *param)
{
	m_threadItem->funcParam = param;
	m_threadItem->handleFunc = func;
}

void MySelfThread::CreateThreadItem(std::function<void(void*)> func, void *param)
{
	m_threadItem = new ThreadItem;
	m_threadItem->handleFunc = func;
	m_threadItem->funcParam = param;
	m_threadItem->pThat = (void *)this;

}

//ThreadPool.h
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <vector>
#include "MySelfThread.h"
class ThreadPool
{
public:
	static ThreadPool*GetInstance();

	virtual ~ThreadPool();

	void Init(int threadNum);

	void Active(std::function<void(void*)> func, void *param);
	/*把工作线程列到空闲队列*/
	void RealseTsk(void *pTHis);
	//结束线程
	void UnInit();
private:
	ThreadPool();
	//
	static ThreadPool* m_instance;
	/*要处理的*/
	std::vector<MySelfThread*> m_handleObjectVec;
	/*空闲的*/
	std::vector<MySelfThread*> m_EmptyObjectVec;
	//
	int m_nThreadNum;


};

#endif

//ThreadPool.cpp
#include "ThreadPool.h"
std::mutex g_tlx;

ThreadPool::ThreadPool()
{
}


ThreadPool::~ThreadPool()
{
	UnInit();
}

ThreadPool* ThreadPool::m_instance = nullptr;
ThreadPool*ThreadPool::GetInstance()
{
	/*多线程double-check,线程安全*/
	if (nullptr == m_instance)
	{
		std::unique_lock<std::mutex> lock(g_tlx); // 加锁
		if (nullptr == m_instance)
		{
			m_instance = new ThreadPool;
		}
	}
	return m_instance;
}

void ThreadPool::RealseTsk(void *pTHis)
{
	std::lock_guard<std::mutex> lk(g_tlx);
	MySelfThread* myThreadItem = (MySelfThread*)pTHis;
	std::vector<MySelfThread*>::iterator itor;
	for (itor = m_handleObjectVec.begin(); itor != m_handleObjectVec.end(); itor++)
	{
		if (*itor == myThreadItem)
		{
			m_handleObjectVec.erase(itor);
			break;
		}
	}
	m_EmptyObjectVec.push_back(myThreadItem);
}

void ThreadPool::UnInit()
{
	std::lock_guard<std::mutex> lk(g_tlx);
	std::vector<MySelfThread*>::iterator itor = m_handleObjectVec.begin();
	MySelfThread *pSelfThread = nullptr;
	while (itor != m_handleObjectVec.end())
	{
		pSelfThread = *itor;
		if (pSelfThread)
		{
			pSelfThread->SetIsRunning(false);
			pSelfThread->Realse();
			itor = m_handleObjectVec.erase(itor);

			delete pSelfThread;
			pSelfThread = nullptr;
		}
	}

	itor = m_EmptyObjectVec.begin();
	while (itor != m_EmptyObjectVec.end())
	{
		pSelfThread = *itor;
		if (pSelfThread)
		{
			pSelfThread->SetIsRunning(false);
			pSelfThread->Realse();
			itor = m_EmptyObjectVec.erase(itor);
			delete pSelfThread;
			pSelfThread = nullptr;
		}
	}
}


void ThreadPool::Active(std::function<void(void*)> func, void *param)
{
	std::lock_guard<std::mutex> lk(g_tlx);
	if (m_EmptyObjectVec.size() > 0)
	{
		/*从空闲队列取出来*/
		MySelfThread* myThreadItem;
		std::vector<MySelfThread*>::iterator itor = m_EmptyObjectVec.begin();
		myThreadItem = *itor;

		m_EmptyObjectVec.erase(itor);
		/*加入繁忙队列*/
		m_handleObjectVec.push_back(myThreadItem);
		/*激活*/
		myThreadItem->ActiveRsk(func, param);
	}
	else
	{
		MySelfThread *pThreadItem = new MySelfThread;
		pThreadItem->SetIsRunning(true);
		pThreadItem->CreateThreadItem(nullptr, nullptr);
		pThreadItem->Start();
		m_handleObjectVec.push_back(pThreadItem);
		m_nThreadNum += 1;

		/*激活*/
		pThreadItem->ActiveRsk(func, param);

	}
}

void ThreadPool::Init(int threadNum)
{
	m_nThreadNum = threadNum;
	for (int i = 0; i < threadNum; i++)
	{
		MySelfThread *pThreadItem = new MySelfThread;
		pThreadItem->SetIsRunning(true);
		pThreadItem->CreateThreadItem(nullptr, nullptr);
		pThreadItem->Start();
		m_EmptyObjectVec.push_back(pThreadItem);
	}
}

具体的调用流程:

#include <iostream>
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#include <time.h>
#endif

#include "ThreadPool.h"
using namespace std;

void func(void *param)
{
	cout << "22222"<<endl;
}

void waitMsecs(int msecs)
{
	if (0 == msecs)
	{
		return;
	}
#ifdef _LINUX_
	struct timespec delayTime, elaspedTime;
	delayTime.tv_sec = msecs / 1000;
	delayTime.tv_nsec = (msecs % 1000) * 1000000;
	nanosleep(&delayTime, &elaspedTime);
#endif
#if defined(_MSC_VER)
	Sleep(msecs);
#endif

	return;
}

void func2(void *param)
{
	while (1)
	{
		waitMsecs(1000);
		//
		cout << "111111111\n";
	}
	
}

void func3(void *param)
{
	while (1)
	{
		cout << "333333\n";
		waitMsecs(1000);

	}

}


int main()
{
	ThreadPool::GetInstance()->Init(2);
	ThreadPool::GetInstance()->Active(func3, NULL);
	ThreadPool::GetInstance()->Active(func, NULL);
	waitMsecs(5000);
	ThreadPool::GetInstance()->Active(func2, NULL);
	waitMsecs(50000);
	return 0;
}

如果在Linux需要用编写CMakeLists.txt

#cmake最低版本需求,不加入此行会受到警告信息
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(HELLO) #项目名称

MESSAGE(STATUS "operation system is ${CMAKE_SYSTEM}")  
MESSAGE(STATUS "operation CMAKE_SYSTEM_NAME is ${CMAKE_SYSTEM_NAME}")  
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
	MESSAGE(STATUS "current platform: Windows ")  
else()
    set(CMAKE_CXX_FLAGS "-fPIC -g -o0 -rdynamic -fasynchronous-unwind-tables -pthread -std=c++11 -Wl,--no-as-needed ${CMAKE_CXX_FLAGS}")
endif()

#把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
AUX_SOURCE_DIRECTORY(. SRC_LIST)
#生成应用程序 hello (在windows下会自动生成hello.exe)
ADD_EXECUTABLE(hello ${SRC_LIST})

if(CMAKE_SYSTEM_NAME MATCHES "Windows")
	MESSAGE(STATUS "current platform: Windows ")  
else()
     target_link_libraries(hello  pthread)
endif()

提示:如果需要支持多线程需要添加 -pthread -std=c++11 -Wl,–no-as-needed

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值