• c++11线程池


    大佬写的东西,顶礼膜拜,用到了C++11很多的新知识

    后面附有我的思考,不保证对,“?”处是我疑惑的地方

    ThreadPool.h

    //
    // Created by zfr on 2020/9/20.
    //
    
    #ifndef PRACTICE_THREADPOOL_H
    #define PRACTICE_THREADPOOL_H
    
    #include<vector>
    #include<queue>
    #include<memory>
    #include<thread>
    #include<mutex>
    #include<condition_variable>
    #include<future>
    #include<functional>
    #include<stdexcept>
    
    class ThreadPool{
    public:
        explicit ThreadPool(size_t);//构造函数,explicit禁止初始化时的参数类型的隐式转换
        
        //变长参数模版
        template<class F, class... Args>
                auto enqueue(F&& f, Args&&... args)
                -> std::future<typename std::result_of<F(Args...)>::type>;
        ~ThreadPool();//析构函数
    
    private:
        std::vector<std::thread> workers;   //工作向量空间
        std::queue<std::function<void()> > tasks;   //任务队列
    
        std::mutex queue_mutex; //互斥量
        std::condition_variable condition;  //条件变量
        bool stop;  //停止标志
    };
    
    inline ThreadPool::ThreadPool(size_t threads) :stop (false) {//构造函数,初始化列表初始化stop为false
        for(size_t i = 0; i < threads; ++i){
            workers.emplace_back([this]{//分清楚emplace与push在vector中的区别,emplace效率更高
                for(;;){//相当于while(true)
                    std::function<void()> task;//声明了一个返回值void,无参的函数task
                    {
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        this->condition.wait(lock, [this]{
                            return this->stop || !this->tasks.empty();});//开始stop为false并且tasks为空,阻塞当前线程
                        if(this->stop && this->tasks.empty())//stop为真,并且任务队列为空,直接返回
                            return;
                        task = std::move(this->tasks.front());//将任务队列最前面的任务移给task,函数绑定?回调函数?函数指针?
                        this->tasks.pop();//删除任务队列最前面的任务
                    }
                    task();//执行
                }
            });
        }
    }
    
    //后置返回值 返回了一个异步调用的结果,存储在future中,返回类型为F函数的类型
    //变长参数模版
    template<class F, class... Args>
    auto ThreadPool::enqueue(F&& f, Args&&... args)
    -> std::future<typename std::result_of<F(Args...)>::type> {//后置返回值 返回了一个异步调用的结果,存储在future中,返回类型为F函数的类型
        using return_type = typename std::result_of<F(Args...)>::type;//给返回类型取了个新名字
        //forword作用是获取参数原有类型,和右值引用有关,获取原始数据
        //bind 将后面的变长函数参数和函数f绑定在一起,形成一个新的可调用实体
        //新建一个子线程,把这个新的可调用实体交给子线程去执行
        //返回的是一个shared_ptr智能指针
        auto task = std::make_shared<std::packaged_task<return_type()> >(
                std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
        //将package_task中的future取出来与新的future联系在一起,共享状态值,return_type为返回参数类型
        std::future<return_type> res = task->get_future();
        {
            std::unique_lock<std::mutex> lock(queue_mutex);//用unique_lock对mutex进行包装,管理mutex对象
            
            if (stop)
                throw std::runtime_error("enqueue on stopped ThreadPool");
    
            tasks.emplace([task]() { (*task)(); });//继续将任务加入任务队列;lambda表达式,返回值是一个函数指针???又回调???
        }
        condition.notify_one();//给wait那边发送消息,此时tasks中已有任务,tasks非空
        return res;
    }
    
    inline ThreadPool::~ThreadPool(){
        {
            std::unique_lock<std::mutex> lock(queue_mutex);//用unique_lock包装mutex变量
            stop = true;
        }
        condition.notify_all();//给所有的wait发送通知
        for(std::thread &worker: workers)//等待所有的工作子线程结束,注意引用符号,不知道这里能不能用auto?
            worker.join();
    }
    #endif //PRACTICE_THREADPOOL_H
    
    

    ThreadPool.cpp

    #include<iostream>
    #include "ThreadPool.h"
    
    
    int main(){
        ThreadPool pool(4);
        auto result = pool.enqueue([](int answer) { return answer; }, 42);
        std::cout<<result.get()<<std::endl;
    }
  • 相关阅读:
    挑战程序设计竞赛 2.1 最基础的“穷竭搜索”
    HDU 5145 NPY and girls(莫队算法+乘法逆元)
    BZOJ 4300 绝世好题(位运算)
    HDU 5724 Chess(博弈论)
    BZOJ 1177 [Apio2009]Oil(递推)
    Codeforces 706D Vasiliy's Multiset(可持久化字典树)
    HDU 3374 String Problem (KMP+最小最大表示)
    POJ 2758 Checking the Text(Hash+二分答案)
    HDU 5782 Cycle(KMP+Hash)
    POJ 3450 Corporate Identity(KMP)
  • 原文地址:https://www.cnblogs.com/sunshine-free/p/13702158.html
Copyright © 2020-2023  润新知