复制这位同学:https://blog.csdn.net/liushengxi_root/article/details/83932654
1.概述:什么是线程池
因为程序边运行边创建线程是比较耗时的,所以我们通过池化的思想:在程序开始运行前创建多个线 程,这样,程序在运行时,只需要从线程池中拿来用就可以了.大大提高了程序运行效率。
2.如何实现线程池
一般线程池都会有以下几个部分构成:
- 线程池管理器(ThreadPoolManager): 用于创建并管理线程池
- 工作线程(WorkThread): 线程池中线程
- 任务队列:用于存放没有处理的任务。提供一种缓冲机制。
- 用于添加任务的接口
总的来讲,就是先创建几个线程,然后这些线程等待任务队列,不为空拿出任务执行即可(任务可以是对象,也可以是某个函数)
3.实现:采用C++模板
#pragma once
#ifndef NIMO_THREAD_POOL_H
#define NIMO_THREAD_POOL_H
#include "UtilsLib.h"
//----------------------------------------------------------------------------
#define POOL_THREAD_COUNT 4
//----------------------------------------------------------------------------
template <typename T>
class ThreadPool
{
public:
ThreadPool(int nThreadNum = POOL_THREAD_COUNT); // 默认开启一个线程
~ThreadPool();
public:
bool Append(T* task); // 添加任务
bool Stop(); // 停止线程池
private:
static void* Worker(void* arg); // 工作线程,读取任务队列并执行
void Run(); // 运行
private:
std::vector<std::thread> mWorkers; // 工程线程
std::queue<T*> mTaskQueue; // 任务队列
std::mutex mQueueMutex; // 任务队列的互斥量
std::condition_variable mCondVar;
bool mStoped; // 线程池是否停止
};
//----------------------------------------------------------------------------
// 函数实现
//----------------------------------------------------------------------------
template <typename T>
ThreadPool<T>::ThreadPool(int nThreadNum) :
mStoped(false)
{
int num = (nThreadNum <= 1 ? 1 : nThreadNum);
for (int i = 0; i < num; i++)
{
mWorkers.emplace_back(ThreadPool::Worker, this);
}
}
//----------------------------------------------------------------------------
template <typename T>
ThreadPool<T>::~ThreadPool()
{
if (mStoped == false)
Stop();
}
//----------------------------------------------------------------------------
template <typename T>
bool ThreadPool<T>::Append(T* task)
{
mQueueMutex.lock();
mTaskQueue.push(task);
mQueueMutex.unlock();
mCondVar.notify_one();
return true;
}
//----------------------------------------------------------------------------
template <typename T>
void* ThreadPool<T>::Worker(void* arg)
{
ThreadPool* pool = (ThreadPool*)arg;
pool->Run();
return pool;
}
//----------------------------------------------------------------------------
template <typename T>
void ThreadPool<T>::Run()
{
while (!mStoped)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
std::unique_lock<std::mutex> lock(this->mQueueMutex);
this->mCondVar.wait(lock, [this] {
return this->mStoped || !this->mTaskQueue.empty();
});
// 如果任务队列不为空,就停下来等待唤醒
if (this->mStoped)
{
LOG(INFO) << "Thread Pool Run Function Return";
return;
}
if (this->mTaskQueue.empty())
{
continue;
}
else
{
T* task = mTaskQueue.front();
mTaskQueue.pop();
if (task)
{
task->Run();
delete task;
task = nullptr;
LOG(INFO) << "Hava Run A Request!";
}
}
}
}
//----------------------------------------------------------------------------
template <typename T>
bool ThreadPool<T>::Stop()
{
mStoped = true;
mCondVar.notify_all();
for (auto& w : mWorkers)
{
LOG(INFO) << "Thread Id:" << w.get_id() << ",Thread Release";
w.join();
}
LOG(INFO) << "All Thread Release !!!";
return true;
}
//----------------------------------------------------------------------------
#endif
4.使用:创建Task对象,实现Run方法
class Task
{
public:
typedef void(*pFunc)(void*);
Task(pFunc pf, void* param) :mpParam(param), mpFun(pf) {};
inline void operator()()
{
// mpFun(mpParam);
}
void Run()
{
{
std::unique_lock<std::mutex> lock(mQueueMutex);
std::cout << "发送一个请求:" << *(int*)mpParam << std::endl;;
}
mpFun(mpParam);
}
void* mpParam;
pFunc mpFun;
// 静态函数
static void Worker(void* param)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
{
std::unique_lock<std::mutex> lock(mQueueMutex);
std::cout << "收到一个请求:" << *(int*)param <<
",Id:" << std::this_thread::get_id() << std::endl;
}
}
};
int main()
{
ThreadPool<Task> tp(5);
Task *t = new Task(&Task::Worker, 4);
}