线程池手撕

池式组件

Posted by Jiayang Hu on September 3, 2025

线程池技术简介

线程池是一种并发编程的技术,用于有效地管理和复用线程资源。它由一组预先创建的线程组成,这些线程可以在需要时执行任务,并在任务完成后返回线程池中等待下一个任务。

线程池的主要目的是避免反复创建和销毁线程的开销,以及有效地控制并发线程的数量。通过使用线程池,可以降低系统的负载,并提高任务执行的效率。

以下是线程池的一些关键特点:

  1. 线程池包含一个线程队列和任务队列,任务队列用于存储待执行的任务。
  2. 线程池在启动时会创建一定数量的线程,并将它们放入线程队列中。
  3. 当有任务需要执行时,线程池从任务队列中获取任务,并将其分配给空闲的线程执行。
  4. 执行完任务的线程会继续等待下一个任务的到来,而不是被销毁。
  5. 如果任务队列为空,线程池中的线程可以进入睡眠状态,减少资源占用。
  6. 线程池可以限制同时执行的线程数量,避免过多的并发线程导致系统负载过高。

手撕用

#include <bits/stdc++.h>

using namespace std;

class Thread_poolv3{
public:
Thread_poolv3(size_t thread_num = std::thread::hardware_concurrency()) : stop(false) {
    if(thread_num == 0){
        thread_num = 8;
    }
    vector_thread.reserve(thread_num);
    for(size_t i = 0; i < thread_num; i++){
        vector_thread.emplace_back([this](){this->work();});
    }
}

void work(){
    for(;;){
        std::function<void()> task;
        {   
            
            std::unique_lock<std::mutex> lock(mtx);
            condition.wait(lock, [this](){
                return stop || !queue_task.empty();
            });
            if(stop && queue_task.empty()) return;
            task = std::move(queue_task.front());
            queue_task.pop();
        }
        task();
    }
}

template <typename F, typename... Args>
void enqueue(F&& f, Args&&... args){
    function<void()> task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
    {
        std::lock_guard<std::mutex> lock(mtx);
        queue_task.emplace(task);
    }
    condition.notify_one();
}

~Thread_poolv3(){
    {
        std::lock_guard<std::mutex> lock(mtx);
        stop.store(true);
    }
    condition.notify_all();
    for(auto& t : vector_thread){
        if(t.joinable()){
            t.join();
        }
    }
}

private:
    std::atomic_bool                 stop;
    size_t thread_num;
    std::mutex                       mtx;
    std::condition_variable          condition;
    std::vector<std::thread>         vector_thread;  // 线程队列 用向量表示
    std::queue<function<void()>>     queue_task;     // 任务队列 用队列表示
};


void testTask(int id){
    std::cout << "Executing task " << id << " on thread "<< std::this_thread::get_id() << std::endl;
    std::this_thread::sleep_for(std::chrono::microseconds(200));
}


int main(){
    Thread_poolv3 pool(4);
    for(int i = 0; i < 10; i++){
        pool.enqueue(testTask, i);
    }
}