Skip to main content

C++线程池

线程池(Thread Pool)是一种线程管理机制,主要用于限制系统中线程的数量、重用线程资源以及减少线程频繁创建和销毁的开销。它通过维护一个线程集合(通常是固定数量的工作线程),让这些线程来执行任务而不必为每个任务都创建一个新线程。

线程池的核心组件

  • 任务队列:保存需要执行的任务,通常是一个线程安全的队列(如 std::queue 或 std::deque)。
  • 工作线程:线程池中预先创建的线程,用于从任务队列中取任务并执行。
  • 任务提交接口:用于提交任务到线程池,通常使用 std::function<void()> 或 std::packaged_task 等形式来封装任务。
  • 同步机制:用来协调任务队列和工作线程,如互斥锁(std::mutex)和条件变量(std::condition_variable)。

C++线程池的实现

一个简单的 C++ 线程池实现通常包括以下步骤:

1.创建若干个工作线程(线程池启动时创建)。
2.每个工作线程循环等待任务队列中的任务。
3.当有新任务提交时,将任务放入任务队列并通知空闲线程。
4.工作线程从任务队列取出任务并执行。
5.线程池关闭时,停止所有工作线程。

实现

class ThreadPool{
public:
ThreadPool(int numthreads);
~ThreadPool();
void enqueue( std::function<void()> task );
private:
std::list<std::thread> m_works;
std::queue< std::function<void()> > m_tasks;
std::mutex m_mutex;
std::condition_variable m_condition;
int m_numthreads;
bool m_stop;
void workerThread();
}
ThreadPool::ThreadPool(int numthreads):m_stop(false){
for(int i=0;i<numthreads;i++>){
m_works.emplace_back([this]{this->workerThread();})
}
}
ThreadPool::~ThreadPool(){
condition.notify_all();
for(std::thread &worker : m_works){
worker.join();
}
}
void ThreadPool::workerThread() {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(queueMutex);
condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
if (this->stop && this->tasks.empty()) {
return;
}
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
}

优点

减少线程创建销毁的开销:线程池中的线程是复用的,避免了频繁的线程创建和销毁。
提高资源利用率:限制并发线程的数量,防止系统因线程过多而导致资源耗尽。
任务提交简单:通过封装任务函数,可以异步提交任务,并获取结果。

常见面试问题

线程池如何管理任务队列? 线程池如何实现负载均衡? 线程池中的线程是如何被回收和销毁的? 如何处理线程池中的异常?