使用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
- 使用C++ 11特性写一个简单的线程池
- 写一个简单的线程池
- 使用linux系统函数和c++03类写的一个简单线程池
- 写的一个简单的java线程池
- Java: 动手写一个简单的线程池
- 自己动手,写一个简单的线程池(1)
- 自己动手,写一个简单的线程池(2)
- 自己动手,写一个简单的线程池(3)
- 写一个简单的java线程吧
- 多线程学习---写一个简单的线程
- c写的一个简单的计算器
- 一个简单的线程池的实现(C++)
- 一个简单的线程池的实现(C++)
- C语言实现一个简单的线程池
- 一个简单线程池的实现 --C语言
- 使用JNI写一个简单的程序
- 使用common-pool实现的一个简单的线程池
- 使用common-pool实现的一个简单的线程池
- 面试感悟----一名3年工作经验的程序员应该具备的技能
- swift项目Cocoapods更新报错和找不到pods头文件报错
- 关于java
- DOXYGEN简明实用教程
- 如何监听listview的滚动事件——获取listview有效滑动的距离
- 使用C++ 11特性写一个简单的线程池
- Activity进入退出动画总结
- Github 教程
- windows 环境下Eclipse开发MapReduce环境设置
- Spring Aop详尽教程
- Android之AsyncTask异步任务——防止内存泄露
- Codeforces 629 D Finals in arithmetic(最大上升子序列和,O(nlogn)、线段树/树状数组)
- 在WPF的TreeView中实现右键选定
- UVa 11478 Halum BellmanFord判负权环