代码拉取完成,页面将自动刷新
#pragma once
#include "mutex.hpp"
#include "cond.hpp"
#include "pthread.hpp"
#include "Log.hpp"
#include <vector>
#include <queue>
#include <functional>
#include <utility>
#define default_thread_num 10
namespace bksw
{
template<typename T>
class pthread_pool
{
private:
std::vector<bksw::pthread> _vp; // 工作线程数组,任务类型与队列统一
std::queue<T> _qt; // 任务队列
int _thread_num; // 线程数量(原_capacity重命名)
mutex _mutex; // 保护队列与状态的互斥锁
cond _con; // 条件变量
statue _st; // 线程池状态
// 单例静态成员
static pthread_pool<T>* _sppt;
static mutex _lock;
// 工作线程核心执行函数
void Execute()
{
while (true)
{
// 1. 加锁,所有共享状态的读写都在锁内
_mutex.lock();
// 2. 队列为空 且 线程池运行中 → 等待
// while 循环规避虚假唤醒,同时判断状态保证停止时能退出
while (_qt.empty() && _st == statue::RUNNING)
{
_con.wait(_mutex);
}
// 3. 退出条件:线程池已停止 且 队列为空
if (_st == statue::STOP && _qt.empty())
{
_mutex.unlock();
break;
}
// 4. 取出任务,立即解锁,避免任务执行时长占用锁
T task = std::move(_qt.front());
_qt.pop();
_mutex.unlock();
// 5. 锁外执行任务
task();
}
}
// 单例:构造函数私有化
explicit pthread_pool(int thread_num)
: _thread_num(thread_num)
, _st(statue::NEW)
{
for (int i = 0; i < _thread_num; ++i)
{
// 预先构造线程对象,不启动;不使用detach
bksw::pthread ptd;
_vp.emplace_back(ptd);
LOG(Loglevel::INFO) << "线程池初始化线程 " << i << " 完成";
}
}
public:
// 禁用拷贝与赋值
pthread_pool(const pthread_pool&) = delete;
pthread_pool& operator=(const pthread_pool&) = delete;
// 单例获取接口
static pthread_pool<T>* GetInstance(int thread_num = default_thread_num)
{
// 双重检查锁定(DCL)
if (_sppt == nullptr)
{
guidemutex guard(_lock); // RAII守卫锁,自动加解锁,避免死锁
if (_sppt == nullptr)
{
_sppt = new pthread_pool<T>(thread_num);
_sppt->start();
LOG(Loglevel::INFO) << "线程池单例创建成功";
}
}
return _sppt;
}
// 提交任务(多生产者并发调用安全)
template<typename Func, typename... Args>
bool assign(Func&& func, Args&&... args)
{
_mutex.lock();
// 停止状态下不接受新任务,判断在锁内保证原子性
if (_st != statue::RUNNING)
{
_mutex.unlock();
LOG(Loglevel::DEBUG) << "线程池未运行,任务提交失败";
return false;
}
// 包装任务并入队,使用移动语义减少拷贝
_qt.emplace(std::bind(std::forward<Func>(func), std::forward<Args>(args)...));
_mutex.unlock();
// 只唤醒一个等待线程,避免惊群
_con.signal();
return true;
}
// 启动线程池
void start()
{
_mutex.lock();
if (_st != statue::NEW)
{
_mutex.unlock();
return;
}
_st = statue::RUNNING;
_mutex.unlock();
// 先设状态再启动线程,避免状态不一致
for (auto& th : _vp)
{
th.start(&pthread_pool<T>::Execute, this);
}
LOG(Loglevel::DEBUG) << "线程池启动完成";
}
// 停止线程池(优雅退出:处理完所有已入队任务再停止)
void stop()
{
_mutex.lock();
if (_st != statue::RUNNING)
{
_mutex.unlock();
return;
}
_st = statue::STOP;
_mutex.unlock();
// 唤醒所有等待线程,让它们检查退出状态
_con.broadcast();
LOG(Loglevel::DEBUG) << "线程池已发出停止信号";
}
// 等待所有工作线程退出
void join()
{
for (auto& th : _vp)
{
th.join();
}
LOG(Loglevel::INFO) << "所有工作线程已退出";
}
// 析构函数:自动停止并回收线程
~pthread_pool()
{
if (_st == statue::RUNNING)
{
stop();
join();
}
}
};
// 静态成员类外定义
template<typename T>
pthread_pool<T>* pthread_pool<T>::_sppt = nullptr;
template<typename T>
mutex pthread_pool<T>::_lock;
} // namespace bksw
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。