C++搭建线程池

ThreadPool.h

/*
func: 线程池类,声明了线程池的操作。
author: zouyujie
date: 2024.12.2
*/
#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <vector>
using std::vector;
#include <queue>
using std::queue;
#include <thread>
using std::thread;
#include <mutex>
using std::mutex;
using std::unique_lock;
#include <condition_variable>
using std::condition_variable;
#include <functional>

using Task = std::function<void()>;  //函数对象类型

/* 线程池类 */
class ThreadPool
{
public:
    ThreadPool(int min, int max);  //最小线程数,最大线程数
    template<class F,class... Args>
    void add_task(F &&f, Args&&... args) {  //完美转发(万能引用)
        Task task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
        unique_lock<mutex> lk(this->poll_mutex);  //加锁
        if (this->shutdown) return;
        taskQ.push(task);
        this->poll_cond.notify_all();  //唤醒线程执行
    }

    void add_task(Task&); //重载
    int get_live_num();  //获取当前存活线程数
    int get_busy_num();  //获取当前忙碌线程数
    ~ThreadPool();

private:
    queue<Task> taskQ;      //任务队列
    thread manager_thread;  //管理者线程
    vector<thread> worker_threads;  //工作者线程
    int min_num;   //最小线程数
    int max_num;   //最大线程数
    int live_num;  //当前存活线程数
    int busy_num;  //当前忙碌线程数
    int destroy_num;  //当前需要销毁线程数

    mutex poll_mutex;  //线程池的锁
    condition_variable poll_cond;  //线程池的条件变量
    bool shutdown;  //是否销毁线程池,默认是false
    static void manager_execute(void*);  //管理者执行任务,传递当前对象指针
    static void worker_execute(void*);   //工作者执行任务,传递当前对象指针
    static void detach_cur_thread(void*);  //分离销毁当前线程
};

#endif // THREADPOOL_H

ThreadPool.cpp

/*
func: 线程池的实现。
author: zouyujie
date: 2024.12.2
*/
#include "threadpool.h"

#include <iostream>
using std::cout;
using std::endl;

/* 线程池一次销毁或增加线程数 */
#define CHANGE_THREAD_NUMBER 2

ThreadPool::ThreadPool(int min, int max)
{
    this->min_num = min;
    this->max_num = max;
    this->live_num = min;
    this->busy_num = 0;
    this->destroy_num = 0;

    this->shutdown = false;

    /* 初始化管理者线程 */
    this->manager_thread = thread(manager_execute, this);
    /* 初始化工作者线程 */
    this->worker_threads.resize(max_num);
    for (int i=0; i<min_num; i++) {
        this->worker_threads[i] = thread(worker_execute, this);
    }
}

void ThreadPool::add_task(Task &task)
{
    unique_lock<mutex> lk(this->poll_mutex);  //加锁
    if (this->shutdown) return;
    taskQ.push(task);
    this->poll_cond.notify_all();  //唤醒线程执行
}

ThreadPool::~ThreadPool()
{
    unique_lock<mutex> lk(this->poll_mutex);  //加锁,此处不加锁可能出现各种问题,如:相互阻塞,异常终止等。
    this->shutdown = true;
    this->destroy_num = 0;
    lk.unlock();  //必须解锁,否则相互阻塞
    /* 阻塞回收管理者线程 */
    if (this->manager_thread.joinable()) this->manager_thread.join();
    /* 唤醒并阻塞回收工作者线程 */
    this->poll_cond.notify_all();
    for (int i=0; i<worker_threads.size(); i++) {
        if (worker_threads[i].joinable()) worker_threads[i].join();
    }
}

int ThreadPool::get_live_num()
{
    unique_lock<mutex> lk(this->poll_mutex);  //加锁
    return this->live_num;
}

int ThreadPool::get_busy_num()
{
    unique_lock<mutex> lk(this->poll_mutex);  //加锁
    return this->busy_num;
}

void ThreadPool::detach_cur_thread(void* arg)
{
    ThreadPool* pool = static_cast<ThreadPool*>(arg);  //得到当前线程池对象

    for (int i=0; i<pool->worker_threads.size(); i++) {
        if (pool->worker_threads[i].get_id() == std::this_thread::get_id()) {
            if (pool->worker_threads[i].joinable()) pool->worker_threads[i].detach();
            break;
        }
    }
}

void ThreadPool::worker_execute(void* arg)
{
    ThreadPool* pool = static_cast<ThreadPool*>(arg);  //得到当前线程池对象

    while (1) {
        unique_lock<mutex> lk(pool->poll_mutex);  //加锁
        /* 线程池任务队列为空,且状态正常 */
        while (pool->taskQ.empty() && !pool->shutdown) {
            pool->poll_cond.wait(lk);  //沉睡当前线程

            /* 该线程被唤醒后 */
            if (pool->destroy_num > 0) {  //如果线程池需要销毁线程
                pool->destroy_num--;
                if (pool->live_num > pool->min_num) {  //满足条件则自杀
                    pool->live_num--;
                    std::cout << "threadID:" << std::this_thread::get_id() << "exit..." << std::endl;
                    /* 销毁当前线程 */
                    pool->detach_cur_thread(pool);
                    return;
                }
            }
        }
        /* 线程池任务队列不为空 */
        if (pool->shutdown) {  //如果线程池状态销毁,则自杀
            std::cout << "threadID:" << std::this_thread::get_id() << "exit..." << std::endl;
            return;
        }
        //取一个任务
        Task task = pool->taskQ.front();
        pool->taskQ.pop();
        pool->busy_num++;
        lk.unlock();  //手动解锁
        //执行该任务
        std::cout << "threadID:" << std::this_thread::get_id() << "start working..." << std::endl;
        task();
        //任务执行完毕
        std::cout << "threadID:" << std::this_thread::get_id() << "end working..." << std::endl;
        lk.lock();
        pool->busy_num--;
        lk.unlock();
    }
}

void ThreadPool::manager_execute(void* arg)
{
    ThreadPool* pool = static_cast<ThreadPool*>(arg);  //得到当前线程池对象

    /* 监控 */
    while (true) {
        /* 每3秒检测一次 */
        std::this_thread::sleep_for(std::chrono::seconds(3));

        unique_lock<mutex> lk(pool->poll_mutex);  //加锁

        if (pool->shutdown) {  //线程池对象销毁则自杀
            std::cout << "threadID:" << std::this_thread::get_id() << "exit..." << std::endl;
            return;
        }

        /* 添加线程的情况
         * 任务个数 > 存活线程数 && 存活线程数 < 最大线程数 */
        if (pool->taskQ.size() > pool->live_num && pool->live_num < pool->max_num) {
            int count = 0;  //添加线程个数
            for (int i=0; i<pool->max_num && count<CHANGE_THREAD_NUMBER && pool->live_num<pool->max_num; i++) {
                if (pool->worker_threads[i].get_id() == thread::id()) {
                    std::cout << "Create a new thread..." << std::endl;
                    pool->worker_threads[i] = thread(worker_execute, pool);
                    count++;
                    pool->live_num++;
                }
            }
        }
        /* 销毁线程的情况
         * 忙碌线程数*2 < 存活线程数 && 存活线程数 > 最小线程数 */
        if (pool->busy_num*2 < pool->live_num && pool->live_num > pool->min_num) {
            pool->destroy_num = CHANGE_THREAD_NUMBER;
            pool->poll_cond.notify_all();
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

❀云坠入雾里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值