C++线程池

使用线程情况比较频繁的地方,由于线程的创建及销毁都会产生对资源的占用及性能的损耗。为了优化性能,提升效率,在这种场景中,就应该使用线程池来处理任务。

线程池创建的关键点:
  1. 装载线程的容器,在C++中使用vector
  2. 装载任务的容器,一般使用队列,满足先进先出的特性
  3. 读写任务队列时,需要使用互斥锁,防止多线程读写异常
  4. 线程保活的无限循环中,需要添加一个有任务时运行,无任务时停止的控制器,防止CPU空转。在C++中使用条件变量
  5. 线程启停标识

依据以上关键点,开始编写相应的代码。首次创建线程池类,一般情况下,该类是单例类。

ThreadPool.h

#ifndef THREAD_POOL_H
#define THREAD_POOL_H

#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>

class ThreadPool {
    public: 
        static ThreadPool* GetInstance(int number);
        
    private:
        ThreadPool(int number);
        ~ThreadPool();

    public:
        template<typename F, typename... Args>
        void AddTask(F&& func, Args&&... args)
        {
            std::unique_lock<std::mutex> lock(m_Mutex);
            std::function<void()> task = std::bind(std::forward<F>(func), std::forward<Args>(args)...);
            m_TaskQueue.emplace(std::move(task));
            lock.unlock();

            m_CV.notify_one();
        }

    private:
        // first: thread container
        // second: task queue
        // third: task queue mutex lock
        // forth: thread keep alive condition varible
        // fifth: thread start/stop flag
        // sixth: storage thread count
        std::vector<std::thread> m_Threads;
        std::queue<std::function<void()>> m_TaskQueue;
        std::mutex m_Mutex;
        std::condition_variable m_CV;
        bool m_IsRunning;
        int m_ThreadNum;
};

#endif
#include "ThreadPool.h"

static ThreadPool *pInstance = nullptr;
static std::once_flag flag1;

ThreadPool *ThreadPool::GetInstance(int number)
{
    std::call_once(flag1, [number](){
        pInstance = new ThreadPool(number);
    });
    return pInstance;
}

ThreadPool::ThreadPool(int number)
    : m_ThreadNum(number), m_IsRunning(true)
{
    m_Threads.push_back(std::thread([this](){
        while (true) // thread keep alive
        {
            std::unique_lock<std::mutex> lock(m_Mutex);
            m_CV.wait(lock, [this](){
                bool isEmpty = m_TaskQueue.empty();
                // task is not empty or thread stopped
                return !isEmpty || !m_IsRunning;
            });

            if (!m_IsRunning)// thread stop
            {
                break;
            }
            auto task = m_TaskQueue.front();
            m_TaskQueue.pop();
            lock.unlock();
            task();
        }
    }));
}

ThreadPool::~ThreadPool()
{
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        m_IsRunning = false;
    }

    m_CV.notify_all();
    
    for (auto &t : m_Threads)
    {
        if (t.joinable())
        {
            t.join();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值