126 lines
3.0 KiB
C++
126 lines
3.0 KiB
C++
#include "VrThread.h"
|
|
#include <iostream>
|
|
|
|
VrThread::VrThread(int index)
|
|
: m_nIndex(index)
|
|
, m_bStarted(false)
|
|
, m_bStop(false)
|
|
, m_bHasTask(false)
|
|
, m_fExecFunc(nullptr)
|
|
, m_pParam(nullptr)
|
|
, m_fFinishFunc(nullptr)
|
|
, m_pFinishParam(nullptr)
|
|
{
|
|
}
|
|
|
|
VrThread::~VrThread()
|
|
{
|
|
Stop();
|
|
if (m_execThread.joinable())
|
|
{
|
|
m_execThread.join();
|
|
}
|
|
}
|
|
|
|
int VrThread::Init()
|
|
{
|
|
m_execThread = std::thread(&VrThread::_ExecTask, this);
|
|
|
|
// 等待工作线程启动完成,避免忙等待
|
|
std::unique_lock<std::mutex> lock(m_mutexExec);
|
|
m_cvStarted.wait(lock, [this] {
|
|
return m_bStarted.load();
|
|
});
|
|
|
|
return 0;
|
|
}
|
|
|
|
int VrThread::ExecTask(ThreadExecFunc fExecFunc, void* pParam,
|
|
ExecFinishFunc pExecFinishFunc, void* pFinishParam)
|
|
{
|
|
if (nullptr == fExecFunc) return VrThreadPoolError::InvalidParam;
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lck(m_mutexExec);
|
|
if (m_bHasTask) return VrThreadPoolError::ThreadBusy;
|
|
|
|
m_fExecFunc = fExecFunc;
|
|
m_pParam = pParam;
|
|
m_fFinishFunc = pExecFinishFunc;
|
|
m_pFinishParam = pFinishParam;
|
|
m_bHasTask = true;
|
|
}
|
|
|
|
m_condExec.notify_one();
|
|
return 0;
|
|
}
|
|
|
|
void VrThread::Stop()
|
|
{
|
|
m_bStop = true;
|
|
m_condExec.notify_one(); // 唤醒可能在等待中的线程
|
|
}
|
|
|
|
bool VrThread::IsIdle() const
|
|
{
|
|
// m_bHasTask 是原子变量,可以无锁快速查询
|
|
// 注意:返回值是瞬时快照,调用方使用时状态可能已变化
|
|
return !m_bHasTask;
|
|
}
|
|
|
|
void VrThread::_ExecTask()
|
|
{
|
|
// 通知 Init() 线程已启动
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutexExec);
|
|
m_bStarted = true;
|
|
}
|
|
m_cvStarted.notify_one();
|
|
|
|
while (!m_bStop)
|
|
{
|
|
//std::cout << "[ThreadPool] thread[" << m_nIndex << "] wait" << std::endl;
|
|
|
|
ThreadExecFunc fExecFunc = nullptr;
|
|
void* pParam = nullptr;
|
|
ExecFinishFunc fFinishFunc = nullptr;
|
|
void* pFinishParam = nullptr;
|
|
|
|
{
|
|
std::unique_lock<std::mutex> olck(m_mutexExec);
|
|
m_condExec.wait(olck, [this] {
|
|
return m_bHasTask || m_bStop;
|
|
});
|
|
|
|
// 如果是被 Stop() 唤醒,直接退出
|
|
if (m_bStop) break;
|
|
|
|
// 取出任务数据
|
|
fExecFunc = m_fExecFunc;
|
|
pParam = m_pParam;
|
|
fFinishFunc = m_fFinishFunc;
|
|
pFinishParam = m_pFinishParam;
|
|
|
|
// 清空任务槽
|
|
m_fExecFunc = nullptr;
|
|
m_pParam = nullptr;
|
|
m_fFinishFunc = nullptr;
|
|
m_pFinishParam = nullptr;
|
|
m_bHasTask = false;
|
|
}
|
|
|
|
// 执行用户任务(在锁外执行,避免阻塞其他操作)
|
|
if (fExecFunc)
|
|
{
|
|
//std::cout << "[ThreadPool] thread[" << m_nIndex << "] exec" << std::endl;
|
|
fExecFunc(pParam);
|
|
}
|
|
|
|
// 执行完成回调
|
|
if (fFinishFunc)
|
|
{
|
|
fFinishFunc(pFinishParam);
|
|
}
|
|
}
|
|
}
|