使用C++ 11特性写一个简单的线程池

来源:互联网 发布:网络舆情监控的重要性 编辑:程序博客网 时间:2024/06/09 17:14
#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();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;};// the constructor just launches some amount of workersinline ThreadPool::ThreadPool(size_t threads)    :   stop(false){    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();                    }                    task();                }            }        );}// add new work item to the pooltemplate<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();    return res;}// the destructor joins all threadsinline ThreadPool::~ThreadPool(){    {        std::unique_lock<std::mutex> lock(queue_mutex);        stop = true;    }    condition.notify_all();    for(std::thread &worker: workers)        worker.join();}#endif
#include <iostream>#include <vector>#include <chrono>#include "ThreadPool.h"int main(){    ThreadPool pool(4);    std::vector< std::future<int> > results;    for(int i = 0; i < 8; ++i) {        results.emplace_back(            pool.enqueue([i] {                std::cout << "hello " << i << std::endl;                std::this_thread::sleep_for(std::chrono::seconds(1));                std::cout << "world " << i << std::endl;                return i*i;            })        );    }    for(auto && result: results)        std::cout << result.get() << ' ';    std::cout << std::endl;    return 0;}
// main.cpp//#include <iostream> // std::cout, std::endl#include <vector>   // std::vector#include <string>   // std::string#include <future>   // std::future#include <thread>   // std::this_thread::sleep_for#include <chrono>   // std::chrono::seconds#include "ThreadPool.hpp"int main(){    // 创建一个能够并发执行四个线程的线程池    ThreadPool pool(4);    // 创建并发执行线程的结果列表    std::vector< std::future<std::string> > results;    // 启动八个需要执行的线程任务    for(int i = 0; i < 8; ++i) {        // 将并发执行任务的返回值添加到结果列表中        results.emplace_back(            // 将下面的打印任务添加到线程池中并发执行            pool.enqueue([i] {                std::cout << "hello " << i << std::endl;                // 上一行输出后, 该线程会等待1秒钟                std::this_thread::sleep_for(std::chrono::seconds(1));                // 然后再继续输出并返回执行情况                std::cout << "world " << i << std::endl;                return std::string("---thread ") + std::to_string(i) + std::string(" finished.---");            })        );    }    // 输出线程任务的结果    for(auto && result: results)        std::cout << result.get() << ' ';    std::cout << std::endl;    return 0;}

这里写图片描述

源代码出处:https://github.com/progschj/ThreadPool

0 0
原创粉丝点击