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 保留所有权利
特别好的代码,可以拿来学习。
阅读全文
0 0
- c实现线程池
- 线程池 c 实现
- c++/c实现线程池
- Linux C 实现线程池
- c语言实现线程池
- linux C线程池实现
- c语言实现线程池
- linux c 实现线程池
- <C++> 基于C++11/14/17的线程池实现
- Linux线程池C语言实现
- linux线程池的C语言实现
- linux线程池的C语言实现
- linux线程池的C语言实现
- 分享一个c线程池实现代码
- linux线程池的C语言实现
- 线程池 C++实现
- C语言实现简单线程池
- Linux下C线程池的实现
- 冒泡排序(Bubble sort)
- compass watch Encoding::CompatibilityError on line ["87"] encodings: GBK and UTF-8
- mysql的时间和字符串的转换
- Mac下ssh和sftp的使用
- 常用工具类(一)
- c++11实现线程池
- hive IllegalArgumentException ! event not found
- 正则表达式与Python语言
- angular JS简单实现购物车功能
- redis-desktop-manager-0.8.3 for mac
- 如何配置Apache Solr6.6版本
- ffmpeg解码音频的两种方式(二)根据同步字节解析音频帧
- Redis cluster multi-key operation
- JNI开发基础篇:C语言调用Java中的方法