c++11线程池
 #pragma once
 #include <future>
 #include <vector>
 #include <atomic>
 #include <queue>
 #include <thread>
 #include <mutex>
 namespace std {
 //线程池最大容量,应尽量设小一点
 #define THREADPOOL_MAX_NUM 16
 class ThreadPool
 {
 public:
     ThreadPool(unsigned short size = ) { AddThread(size); }
     ~ThreadPool()
     {
         if (_run.load())
         {
             Close();
         }
     }
     void Close()
     {
         _run.store(false);
         //唤醒所有线程执行
         _task_cv.notify_all();
         for (thread &th : _pool)
         {
             if (th.joinable())
                 th.join();
         }
     }
     //提交一个任务,
     template<class F, class... Args>
     auto commit(F&& f, Args&&... args) ->future<decltype(f(args...))>
     {
         if (!_run)
             throw runtime_error("commit on ThreadPool is stop.");
         // typename std::result_of<F(Args...)>::type, 函数 f 的返回值类型
         using RetType = decltype(f(args...));
         //把函数入口及参数打包
         auto task = make_shared<packaged_task<RetType()>>(bind(forward<F>(f), forward<Args>(args)...));
         future<RetType> future = task->get_future();
         {
             lock_guard<mutex> lock{ _lock };
             _tasks.emplace([task]() {(*task)(); });
         }
 #ifdef THREADPOOL_AUTO_GROW if (_id1ThrNum <  && _pool.size() < THREADPOOL_MAX_NUM) AddThread(); #endif _task_cv.notify_one(); return future; }
 int IdlCount() { return _id1ThrNum; }
     int BusyCount() { return _pool.size(); }
     void AddThread(unsigned short size)
     {
         for (; _pool.size() < THREADPOOL_MAX_NUM && size > ; --size)
         {
             _pool.emplace_back([this] {
                 while (_run.load())
                 {
                     Task task;
                     {
                         unique_lock<mutex> lock{ _lock };
                         _task_cv.wait(lock, [this]
                         {
                             return !_run.load() || !_tasks.empty();
                         });
                         if (!_run.load() && _tasks.empty())
                             return;
                         task = move(_tasks.front());
                         _tasks.pop();
                     }
                     _id1ThrNum--;
                     task();
                     _id1ThrNum++;
                 }
             });
             _id1ThrNum--;
         }
     }
 public:
     //定义类型
     using Task = std::function<void()>;
     //线程池
     vector<thread> _pool;
     //锁
     mutex _lock;
     //任务队列
     queue<Task> _tasks;
     //条件阻塞
     condition_variable _task_cv;
     //线程是否在执行
     atomic<bool> _run{ true };
     //空闲线程
     atomic<int> _id1ThrNum{  };
 };
 }
c++11线程池的更多相关文章
- 托管C++线程锁实现    c++11线程池
		托管C++线程锁实现 最近由于工作需要,开始写托管C++,由于C++11中的mutex,和future等类,托管C++不让调用(报错),所以自己实现了托管C++的线程锁. 该类可确保当一个线程位于 ... 
- 简单的C++11线程池实现
		线程池的C++11简单实现,源代码来自Github上作者progschj,地址为:A simple C++11 Thread Pool implementation,具体博客可以参见Jakob's D ... 
- c++11 线程池学习笔记  (一)  任务队列
		学习内容来自一下地址 http://www.cnblogs.com/qicosmos/p/4772486.html github https://github.com/qicosmos/cosmos ... 
- C++11线程池的实现
		什么是线程池 处理大量并发任务,一个请求一个线程来处理请求任务,大量的线程创建和销毁将过多的消耗系统资源,还增加了线程上下文切换开销. 线程池通过在系统中预先创建一定数量的线程,当任务请求到来时从线程 ... 
- c++11线程池实现
		咳咳.c++11 增加了线程库,从此告别了标准库不支持并发的历史. 然而 c++ 对于多线程的支持还是比較低级,略微高级一点的使用方法都须要自己去实现,譬如线程池.信号量等. 线程池(thread p ... 
- c++ 11 线程池---完全使用c++ 11新特性
		前言: 目前网上的c++线程池资源多是使用老版本或者使用系统接口实现,使用c++ 11新特性的不多,最近研究了一下,实现一个简单版本,可实现任意任意参数函数的调用以及获得返回值. 0 前置知识 首先介 ... 
- 基于C++11线程池
		1.包装线程对象 class task : public std::tr1::enable_shared_from_this<task> { public: task():exit_(fa ... 
- 《java.util.concurrent 包源码阅读》11 线程池系列之ThreadPoolExecutor 第一部分
		先来看ThreadPoolExecutor的execute方法,这个方法能体现出一个Task被加入到线程池之后都发生了什么: public void execute(Runnable command) ... 
- c++11 线程池
		也可参考: https://www.cnblogs.com/ailumiyana/p/10016965.html *** https://blog.csdn.net/jlusuoya/article/ ... 
随机推荐
- 04-GIT TortoiseGit冲突和补丁演示 案例演示
			TortoiseGit安装下载 http://download.tortoisegit.org/tgit/1.8.12.0/ 或https://code.google.com/p/tortoisegi ... 
- Android开机键失灵启动手机的解决办法
			问题描述 Android手机的关机键损坏,无法开机. 解决方法 将手机通过USB线链接电脑,进入命令行,找到adb命令所在目录,运行如下命令: adb reboot 注意:用这种方法的前提是,如果你当 ... 
- Android 仿百合网超火爆社交app首页滑动效果
			探探,百合网等神器的首页有一个相册加载个控件,通过左滑右滑加载新的照片,同时左滑丢弃这个照片,右滑则表明对这个照片感兴趣. 这个效果是怎么实现的呢? 1,Android3.0以后控件中增加了setTr ... 
- Swift语言学习路线图
- OpenCV特征点检测算法对比
			识别算法概述: SIFT/SURF基于灰度图, 一.首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点, ... 
- JavaScript进阶(六)用JavaScript读取和保存文件
			用JavaScript读取和保存文件 因为Google还不提供同步插件数据的功能,所以导入和导出插件配置就必须和文件打交道了.而出于安全原因,只有IE才提供访问文件的API:但随着HTML 5的到来, ... 
- 生产者消费者的java实现
			先看最简单的,也就是缓冲区的容量为1 缓冲区容量为1 import java.util.List; public class ProducerAndConsumer2 { static class A ... 
- DB 查询分析器 6.03 如何灵活、快捷地操作国产达梦数据库
			DB 查询分析器 6.03 如何灵活.快捷地操作国产达梦数据库 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要 本文详细地介绍了"万能数据库查询分析器&qu ... 
- vs2010修改状态栏的CStatusBar指针的的SetPaneText()方法时死活不对问题
			vs2010的mfc在有些地方不太一样不容易注意到,今天在修改状态栏的时候,就碰见了问题,死活修改不了. 参照下面的帖子: 点击打开链接 : 使用VS2010更改MFC程序的状态栏 2011-04-1 ... 
- Nginx常用模块安装命令
			将目录切换至Nginx安装包目录下,使用./configure命令进行安装.一些第三方模块需要先下载过来,指定下解压后的目录即可. ./configure --prefix=/usr/local/ng ... 
