Files
EzUI/sources/Task.cpp

133 lines
3.0 KiB
C++
Raw Permalink Normal View History

2026-01-24 22:42:46 +08:00
#include "Task.h"
namespace ezui {
Mutex::Mutex() {
InitializeCriticalSection(&m_mtx); // 初始化互斥锁
m_bLocked = false;
}
Mutex::~Mutex() {
DeleteCriticalSection(&m_mtx); // 销毁互斥锁
}
void Mutex::Lock() {
EnterCriticalSection(&m_mtx);
m_bLocked = true;
}
void Mutex::UnLock() {
LeaveCriticalSection(&m_mtx);
m_bLocked = false;
}
ConditionVariable::ConditionVariable() {
m_codv = CreateEvent(NULL, FALSE, FALSE, NULL); // 创建事件对象
}
ConditionVariable::~ConditionVariable() {
if (m_codv != NULL) {
CloseHandle(m_codv); // 关闭句柄,释放资源
}
}
void ConditionVariable::Notify() {
SetEvent(m_codv); // 设置事件,唤醒等待的线程
}
void ConditionVariable::Wait(const std::function<bool()>& condition_cb) {
m_mtx.Lock();// 先加锁
// 如果没有条件回调的情况下
if (!condition_cb) {
m_mtx.UnLock(); // 必须先解锁再等待!
WaitForSingleObject(m_codv, INFINITE);
return; //事件已触发 无需再检查 等待信号之前已经解锁 所以无需解锁 直接return
}
// 如果有条件回调 循环检查
while (!condition_cb()) {
m_mtx.UnLock(); // 解锁后再等待,避免死锁
WaitForSingleObject(m_codv, INFINITE);
m_mtx.Lock(); // 重新加锁检查条件
}
m_mtx.UnLock(); // 最终解锁
}
void ConditionVariable::Lock() {
m_mtx.Lock();
}
void ConditionVariable::Unlock() {
m_mtx.UnLock();
}
}
namespace ezui {
void Task::Wait() {
if (!m_bJoin)
{
m_bJoin = true;
m_thread->join(); // 等待线程完成
}
}
bool Task::IsStopped() {
return m_finished;
}
void Task::DoWork(std::function<void()>* func) {
(*func)(); // 执行任务
delete func;
m_finished = true;
}
Task::~Task() {
Wait(); // 等待任务完成
delete m_thread; // 删除线程对象
}
TaskFactory::TaskFactory(int maxTaskCount) {
for (size_t i = 0; i < maxTaskCount; ++i)
{
m_tasks.push_back(new Task([this]() {
while (true)
{
std::function<void()> task;
{
std::unique_lock<std::mutex> autoLock(this->m_mtx);
this->m_codv.wait(autoLock, [this]()->bool {
return this->m_bStop || !this->m_funcs.empty();
});
if (m_funcs.empty()) {
this->m_codv2.notify_all();
}
if (this->m_bStop && m_funcs.empty()) {
break;
}
task = std::move(*m_funcs.begin());
m_funcs.pop_front();
}
task();
}
}));
}
}
void TaskFactory::WaitAll() {
m_codv.notify_all();
std::unique_lock<std::mutex> lock2(this->m_mtx2);
this->m_codv2.wait(lock2, [this]()->bool {
return m_funcs.empty();
});
}
TaskFactory::~TaskFactory() {
{
std::unique_lock<std::mutex> autoLock(m_mtx);
m_bStop = true;
}
WaitAll();
while (!m_tasks.empty())
{
for (auto itor = m_tasks.begin(); itor != m_tasks.end(); )
{
if ((*itor)->IsStopped()) {
(*itor)->Wait();
delete (*itor);
itor = m_tasks.erase(itor);
}
else {
++itor;
}
}
}
}
};