97 lines
2.4 KiB
C++
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();
|
|
} });
|
|
}
|
|
}
|