//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