SwitchGame/source/Tool/ThreadPool.cpp

97 lines
2.4 KiB
C++

#include "ThreadPool.h"
#include <stdexcept>
#include <cstdio>
// 获取单例实例
ThreadPool &ThreadPool::GetInstance()
{
static ThreadPool instance(3); // 固定3个工作线程
return instance;
}
ThreadPool::~ThreadPool()
{
shutdown();
}
void ThreadPool::shutdown()
{
printf("ThreadPool destroyed\n");
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
// 清空所有线程的任务队列
for (auto &queue : threadTasks)
{
// 使用swap技巧清空队列
std::queue<std::function<void()>> empty;
std::swap(queue, empty);
}
}
// 通知所有线程
for (auto &cond : threadConditions)
cond->notify_all();
for (std::thread &worker : workers)
if (worker.joinable())
worker.join();
// 释放条件变量
for (auto &cond : threadConditions)
delete cond;
}
// 获取线程池大小
size_t ThreadPool::size() const
{
return workers.size();
}
// 获取指定线程的负载(待处理任务数)
size_t ThreadPool::getThreadLoad(int threadId) const
{
if (threadId < 0 || threadId >= static_cast<int>(workers.size()))
throw std::runtime_error("Invalid thread ID");
std::unique_lock<std::mutex> lock(queue_mutex);
return threadTasks.at(threadId).size();
}
// 私有构造函数实现
ThreadPool::ThreadPool(size_t numThreads) : stop(false)
{
// 为每个线程创建任务队列
threadTasks.resize(numThreads);
// 为每个线程创建条件变量
for (size_t i = 0; i < numThreads; ++i)
{
threadConditions.push_back(new std::condition_variable());
}
for (size_t i = 0; i < numThreads; ++i)
{
workers.emplace_back([this, i]
{
while(true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->threadConditions[i]->wait(lock, [this, i] {
return this->stop || !this->threadTasks[i].empty();
});
if(this->stop && this->threadTasks[i].empty())
return;
task = std::move(this->threadTasks[i].front());
this->threadTasks[i].pop();
}
task();
} });
}
}