zoukankan      html  css  js  c++  java
  • C++ --- 基于std::thread实现的线程池

    #ifndef THREAD_POOL_H
    #define THREAD_POOL_H
    
    #include <vector>
    #include <queue>
    #include <memory>
    #include <thread>
    #include <mutex>
    #include <condition_variable>
    #include <future>
    #include <functional>
    #include <stdexcept>
    
    class ThreadPool {
    public:
        ThreadPool(size_t);
        template<class F, class... Args>
        auto enqueue(F&& f, Args&&... args)
            -> std::future<typename std::result_of<F(Args...)>::type>;
        ~ThreadPool();
    //    int GetFreeThreadNum(){return freeThreadNum;}
        int num;//向线程池push的任务总数,没有加锁
    
    private:
        // need to keep track of threads so we can join them
        std::vector< std::thread > workers;
        // the task queue
        std::queue< std::function<void()> > tasks;
        
        // synchronization
        std::mutex queue_mutex;
        std::condition_variable condition;
        bool stop;
    //    std::atomic<int> freeThreadNum;//线程池空闲线程数量
    };
     
    // the constructor just launches some amount of workers
    inline ThreadPool::ThreadPool(size_t threads)
        :   stop(false)
        ,num(0)
    {
    //    freeThreadNum = threads;
        for(size_t i = 0;i<threads;++i)
            workers.emplace_back(
                [this]
                {
                    for(;;)
                    {
                        std::function<void()> task;
    
                        {
                            std::unique_lock<std::mutex> lock(this->queue_mutex);
                            this->condition.wait(lock,
                                [this]{ return this->stop || !this->tasks.empty(); });//没有要执行任务的时候,线程沉睡(不会浪费资源)
    
                            if(this->stop && this->tasks.empty())
                                return;
    
                            task = std::move(this->tasks.front());
                            this->tasks.pop();
                        }
    
    //                    freeThreadNum--;
                        task();
    //                    freeThreadNum++;
                    }
                }
            );
    }
    
    // add new work item to the pool
    template<class F, class... Args>
    auto ThreadPool::enqueue(F&& f, Args&&... args) 
        -> std::future<typename std::result_of<F(Args...)>::type>
    {
        using return_type = typename std::result_of<F(Args...)>::type;
    
        auto task = std::make_shared< std::packaged_task<return_type()> >(
                std::bind(std::forward<F>(f), std::forward<Args>(args)...)
            );
            
        std::future<return_type> res = task->get_future();
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
    
            // don't allow enqueueing after stopping the pool
            if(stop)
                throw std::runtime_error("enqueue on stopped ThreadPool");
    
            tasks.emplace([task](){ (*task)(); });
        }
        condition.notify_one();
    //    num++;
        return res;
    }
    
    // the destructor joins all threads
    inline ThreadPool::~ThreadPool()
    {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;
        }
        condition.notify_all();
        for(std::thread &worker: workers)
            worker.join();
    }
    
    #endif

    说明:

    ThreadPool(size_t threadsNum); 构造函数,通过threadsNum指定线程池的大小。
    auto enqueue(F&& f, Args&&... args); 需要放到线程池中运行的函数,和参数。
    ~ThreadPool(); 析构函数,在线程池对象销毁的时候,如果线程池中还有未执行的任务,会依次唤醒,并执行完成,最后结束线程池中所有线程。

  • 相关阅读:
    linux 短信收发
    sama5d3 环境检测 adc测试
    【Codeforces 723C】Polycarp at the Radio 贪心
    【Codeforces 723B】Text Document Analysis 模拟
    【USACO 2.2】Preface Numbering (找规律)
    【Codeforces 722C】Destroying Array (数据结构、set)
    【USACO 2.1】Hamming Codes
    【USACO 2.1】Healthy Holsteins
    【USACO 2.1】Sorting A Three-Valued Sequence
    【USACO 2.1】Ordered Fractions
  • 原文地址:https://www.cnblogs.com/linxisuo/p/14966996.html
Copyright © 2011-2022 走看看