GrabBag/Module/ThreadPool/Src/VrThreadPool.cpp

198 lines
5.2 KiB
C++
Raw Normal View History

2026-03-28 10:49:55 +08:00
#include "VrThreadPool.h"
2026-06-20 23:36:24 +08:00
#include <thread>
#include <chrono>
2026-03-28 10:49:55 +08:00
2026-06-20 23:36:24 +08:00
// ============================================================================
// IVrThreadPool 静态工厂方法
// ============================================================================
bool IVrThreadPool::CreateThreadPool(IVrThreadPool** ppThreadPool, int maxThreadCount)
{
if (nullptr == ppThreadPool) return false;
*ppThreadPool = new VrThreadPool(maxThreadCount);
return true;
}
// ============================================================================
// VrThreadPool 构造 / 析构
// ============================================================================
VrThreadPool::VrThreadPool(int maxThreadCount)
: m_nMaxThreadCount(maxThreadCount)
, m_bStop(false)
{
// 0: 使用硬件并发数;负数(如 -1: 不限制线程数
if (m_nMaxThreadCount == 0)
{
unsigned int hwThreads = std::thread::hardware_concurrency();
m_nMaxThreadCount = static_cast<int>(hwThreads > 0 ? hwThreads : 4);
}
}
VrThreadPool::~VrThreadPool()
2026-03-28 10:49:55 +08:00
{
2026-06-20 23:36:24 +08:00
Stop();
// 等待所有线程结束并释放资源
for (VrThread* pThread : m_vetThread)
{
if (pThread)
{
delete pThread;
}
}
2026-03-28 10:49:55 +08:00
m_vetThread.clear();
m_deqRecoveryThread.clear();
2026-06-20 23:36:24 +08:00
m_deqPendingTasks.clear();
2026-03-28 10:49:55 +08:00
}
2026-06-20 23:36:24 +08:00
// ============================================================================
// 公开接口
// ============================================================================
int VrThreadPool::ExecTask(ThreadExecFunc fExecFunc, void* pParam)
2026-03-28 10:49:55 +08:00
{
2026-06-20 23:36:24 +08:00
if (nullptr == fExecFunc) return VrThreadPoolError::InvalidParam;
2026-03-28 10:49:55 +08:00
2026-06-20 23:36:24 +08:00
VrThread* pThread = nullptr;
bool needInit = false;
{
std::lock_guard<std::mutex> lck(m_mutexPool);
// 1. 优先从回收队列取空闲线程
if (!m_deqRecoveryThread.empty())
{
pThread = m_deqRecoveryThread.front();
m_deqRecoveryThread.pop_front();
}
// 2. 未达上限,创建新线程
else if (m_nMaxThreadCount < 0
|| static_cast<int>(m_vetThread.size()) < m_nMaxThreadCount)
{
pThread = new VrThread(static_cast<int>(m_vetThread.size()));
m_vetThread.push_back(pThread);
needInit = true;
}
// 3. 已达上限,放入等待队列
else
{
m_deqPendingTasks.emplace_back(fExecFunc, pParam);
return VrThreadPoolError::Ok;
}
}
// 新线程在锁外初始化Init 会阻塞直到线程启动)
if (needInit)
{
pThread->Init();
}
return pThread->ExecTask(
fExecFunc,
pParam,
std::bind(&VrThreadPool::_ExecFinish, this, std::placeholders::_1),
pThread
);
2026-03-28 10:49:55 +08:00
}
2026-06-20 23:36:24 +08:00
bool VrThreadPool::WaitAllTaskFinish(int timeoutMs)
2026-03-28 10:49:55 +08:00
{
2026-06-20 23:36:24 +08:00
std::unique_lock<std::mutex> lock(m_mutexPool);
2026-03-28 10:49:55 +08:00
2026-06-20 23:36:24 +08:00
auto allIdle = [this] {
// 无线程 或 (所有线程空闲 且 无等待任务)
return m_vetThread.empty()
|| (m_deqRecoveryThread.size() == m_vetThread.size()
&& m_deqPendingTasks.empty());
};
if (timeoutMs <= 0)
{
m_cvIdle.wait(lock, allIdle);
return true;
}
else
2026-03-28 10:49:55 +08:00
{
2026-06-20 23:36:24 +08:00
return m_cvIdle.wait_for(lock, std::chrono::milliseconds(timeoutMs), allIdle);
2026-03-28 10:49:55 +08:00
}
2026-06-20 23:36:24 +08:00
}
void VrThreadPool::Stop()
{
m_bStop = true;
// 通知所有线程停止
for (VrThread* pThread : m_vetThread)
{
if (pThread)
{
pThread->Stop();
}
}
}
2026-03-28 10:49:55 +08:00
2026-06-20 23:36:24 +08:00
int VrThreadPool::GetThreadCount() const
{
std::lock_guard<std::mutex> lck(m_mutexPool);
return static_cast<int>(m_vetThread.size());
2026-03-28 10:49:55 +08:00
}
2026-06-20 23:36:24 +08:00
int VrThreadPool::GetIdleThreadCount() const
2026-03-28 10:49:55 +08:00
{
2026-06-20 23:36:24 +08:00
std::lock_guard<std::mutex> lck(m_mutexPool);
return static_cast<int>(m_deqRecoveryThread.size());
}
int VrThreadPool::GetPendingTaskCount() const
{
std::lock_guard<std::mutex> lck(m_mutexPool);
return static_cast<int>(m_deqPendingTasks.size());
}
// ============================================================================
// 内部方法
// ============================================================================
void VrThreadPool::_ExecFinish(void* pObject)
{
if (m_bStop) return;
2026-03-28 10:49:55 +08:00
VrThread* pThread = reinterpret_cast<VrThread*>(pObject);
2026-06-20 23:36:24 +08:00
if (!pThread) return;
ThreadExecFunc nextFunc = nullptr;
void* nextParam = nullptr;
2026-03-28 10:49:55 +08:00
{
std::lock_guard<std::mutex> lck(m_mutexPool);
2026-06-20 23:36:24 +08:00
// 有排队任务 → 当前线程直接复用,不进入回收队列
if (!m_deqPendingTasks.empty())
{
auto& task = m_deqPendingTasks.front();
nextFunc = task.first;
nextParam = task.second;
m_deqPendingTasks.pop_front();
}
else
{
// 无排队任务 → 放回回收队列
m_deqRecoveryThread.push_front(pThread);
}
}
if (nextFunc)
{
// 在当前线程上直接执行下一个排队任务(跳过回收→取出环节)
pThread->ExecTask(
nextFunc,
nextParam,
std::bind(&VrThreadPool::_ExecFinish, this, std::placeholders::_1),
pThread
);
2026-03-28 10:49:55 +08:00
}
2026-06-20 23:36:24 +08:00
m_cvIdle.notify_one(); // 通知 WaitAllTaskFinish
}