c++11实现线程池

来源:互联网 发布:物业投标书网络范围 编辑:程序博客网 时间:2024/06/06 15:39
测试程序//// 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.h"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;}

线程池类

// // ThreadPool.hpp// ThreadPool// // Original Author: Jakob Progsch, Václav Zeman// Modified By:     https://www.shiyanlou.com// Original Link:   https://github.com/progschj/ThreadPool//#ifndef ThreadPool_hpp#define ThreadPool_hpp#include <vector>               // std::vector#include <queue>                // std::queue#include <memory>               // std::make_shared#include <stdexcept>            // std::runtime_error#include <thread>               // std::thread#include <mutex>                // std::mutex,        std::unique_lock#include <condition_variable>   // std::condition_variable#include <future>               // std::future,       std::packaged_task#include <functional>           // std::function,     std::bind#include <utility>              // std::move,         std::forwardclass ThreadPool {public:    inline ThreadPool(size_t threads) : stop(false) {         // 启动 threads 数量的工作线程(worker)    for(size_t i = 0;i<threads;++i)        workers.emplace_back(            // 此处的 lambda 表达式捕获 this, 即线程池实例            [this]            {                // 循环避免虚假唤醒                for(;;)                {                    // 定义函数对象的容器, 存储任意的返回类型为 void 参数表为空的函数                    std::function<void()> task;                    // 临界区                    {                        // 创建互斥锁                        std::unique_lock<std::mutex> lock(this->queue_mutex);                        // 阻塞当前线程, 直到 condition_variable 被唤醒                        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();                }            }        );    }    template<class F, class... Args>    auto 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 对象以供实施线程同步    std::future<return_type> res = task->get_future();    // 临界区    {        std::unique_lock<std::mutex> lock(queue_mutex);        // 禁止在线程池停止后加入新的线程        if(stop)            throw std::runtime_error("enqueue on stopped ThreadPool");        // 将线程添加到执行任务队列中        tasks.emplace([task]{ (*task)(); });    }    // 通知一个正在等待的线程    condition.notify_one();    return res;    }    inline ~ThreadPool() {// 临界区    {        // 创建互斥锁        std::unique_lock<std::mutex> lock(queue_mutex);        // 设置线程池状态        stop = true;    }    // 通知所有等待线程    condition.notify_all();    // 使所有异步线程转为同步执行, 此处循环为 c++11 新提供的循环语法 for(value:values)    for(std::thread &worker: workers)        worker.join();    }private:    // 需要持续追踪线程来保证可以使用 join    std::vector< std::thread > workers;    // 任务队列    std::queue< std::function<void()> > tasks;    // 同步相关    std::mutex queue_mutex;             // 互斥锁    std::condition_variable condition;  // 互斥条件变量    // 停止相关    bool stop;};#endif /* ThreadPool_hpp */

这段代码的来源:https://github.com/progschj/ThreadPool 原作者 Jakob Progsch, Václav Zeman 保留所有权利
特别好的代码,可以拿来学习。

原创粉丝点击