简单实用C++11现实线程池

#ifndef THREAD_POOL_H
#define THREAD_POOL_H

#include <vector>
#include <queue>
#include <atomic>
#include <future>
//#include <condition_variable>
//#include <thread>
//#include <functional>
#include <stdexcept>

//线程池最大容量,应尽量设小一点
#define  THREADPOOL_MAX_NUM 16
//#define  THREADPOOL_AUTO_GROW

//线程池,可以提交变参函数或拉姆达表达式的匿名函数执行,可以获取执行返回值
//不直接支持类成员函数, 支持类静态成员函数或全局函数,Opteron()函数等
class ThreadPool
{
    typedef std::function<void()> Task; //定义类型
    std::vector<std::thread> _pool;          //线程池
    std::queue<Task> _tasks;            //任务队列
    std::mutex _lock;                   //同步
    std::condition_variable _task_cv;   //条件阻塞
    std::atomic<bool> _run;     //线程池是否执行
    std::atomic<int>  _idlThrNum;  //空闲线程数量

public:
    inline ThreadPool(unsigned short size = 4)
    {
        _run = true;
        _idlThrNum = 0;
        AddThread(size);
    }

    inline ~ThreadPool()
    {
        _run=false;
        _task_cv.notify_all(); // 唤醒所有线程执行
        for (std::thread& thread : _pool) {
            //thread.detach(); // 让线程“自生自灭”
            if(thread.joinable())
                thread.join(); // 等待任务结束, 前提:线程一定会执行完
        }
    }

public:
    int IdlCount();

    int ThreadCount();

    template<class F, class... Args>
    auto Commit(F&& f, Args&&... args)
    -> std::future<typename std::result_of<F(Args...)>::type>;

private:
    void AddThread(unsigned short size);

};

template<class F, class... Args>
auto ThreadPool::Commit(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>
{
    if (!_run)
    {
        throw std::runtime_error("Commit on ThreadPool is stopped.");
    }

    typedef typename std::result_of<F(Args...)>::type return_type;

    auto task = std::make_shared<std::packaged_task<return_type()> >(  //指向F函数的智能指针
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)  //传递函数进行构造
        );

    std::future<return_type> future = task->get_future();
    {    // 添加任务到队列
        std::lock_guard<std::mutex> lock{ _lock };//对当前块的语句加锁  lock_guard 是 mutex 的 stack 封装类,构造的时候 lock(),析构的时候 unlock()
        _tasks.emplace([task](){ // push(Task{...}) 放到队列后面
            (*task)();
        });
    }

    _task_cv.notify_one(); // 唤醒一个线程执行

    return future;
}

#endif

#include "Base/ThreadPool.h"

//空闲线程数量
int ThreadPool::IdlCount()
{
    return _idlThrNum;
}

//线程数量
int ThreadPool::ThreadCount()
{
    return _pool.size();
}

void ThreadPool::AddThread(unsigned short size)
{
    for (; _pool.size() < THREADPOOL_MAX_NUM && size > 0; --size)
    {   //增加线程数量,但不超过 预定义数量 THREADPOOL_MAX_NUM
        _pool.emplace_back( [this]{ //工作线程函数
            while (_run)
            {
                Task task; // 获取一个待执行的 task
                {
                    // unique_lock 相比 lock_guard 的好处是:可以随时 unlock() 和 lock()
                    std::unique_lock<std::mutex> lock{ _lock };
                    _task_cv.wait(lock, [this]{
                            return !_run || !_tasks.empty();
                    }); // wait 直到有 task
                    if (!_run && _tasks.empty())
                        return;
                    task = move(_tasks.front()); // 按先进先出从队列取一个 task
                    _tasks.pop();
                }
                _idlThrNum--;
                task();//执行任务
                _idlThrNum++;
            }
        });
        _idlThrNum++;
    }
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章