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(); | ||
|  |             } }); | ||
|  |     } | ||
|  | } |