#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线程池的更多相关文章

  1. 托管C++线程锁实现 c++11线程池

    托管C++线程锁实现   最近由于工作需要,开始写托管C++,由于C++11中的mutex,和future等类,托管C++不让调用(报错),所以自己实现了托管C++的线程锁. 该类可确保当一个线程位于 ...

  2. 简单的C++11线程池实现

    线程池的C++11简单实现,源代码来自Github上作者progschj,地址为:A simple C++11 Thread Pool implementation,具体博客可以参见Jakob's D ...

  3. c++11 线程池学习笔记 (一) 任务队列

    学习内容来自一下地址 http://www.cnblogs.com/qicosmos/p/4772486.html github https://github.com/qicosmos/cosmos ...

  4. C++11线程池的实现

    什么是线程池 处理大量并发任务,一个请求一个线程来处理请求任务,大量的线程创建和销毁将过多的消耗系统资源,还增加了线程上下文切换开销. 线程池通过在系统中预先创建一定数量的线程,当任务请求到来时从线程 ...

  5. c++11线程池实现

    咳咳.c++11 增加了线程库,从此告别了标准库不支持并发的历史. 然而 c++ 对于多线程的支持还是比較低级,略微高级一点的使用方法都须要自己去实现,譬如线程池.信号量等. 线程池(thread p ...

  6. c++ 11 线程池---完全使用c++ 11新特性

    前言: 目前网上的c++线程池资源多是使用老版本或者使用系统接口实现,使用c++ 11新特性的不多,最近研究了一下,实现一个简单版本,可实现任意任意参数函数的调用以及获得返回值. 0 前置知识 首先介 ...

  7. 基于C++11线程池

    1.包装线程对象 class task : public std::tr1::enable_shared_from_this<task> { public: task():exit_(fa ...

  8. 《java.util.concurrent 包源码阅读》11 线程池系列之ThreadPoolExecutor 第一部分

    先来看ThreadPoolExecutor的execute方法,这个方法能体现出一个Task被加入到线程池之后都发生了什么: public void execute(Runnable command) ...

  9. c++11 线程池

    也可参考: https://www.cnblogs.com/ailumiyana/p/10016965.html *** https://blog.csdn.net/jlusuoya/article/ ...

随机推荐

  1. 04-GIT TortoiseGit冲突和补丁演示 案例演示

    TortoiseGit安装下载 http://download.tortoisegit.org/tgit/1.8.12.0/ 或https://code.google.com/p/tortoisegi ...

  2. Android开机键失灵启动手机的解决办法

    问题描述 Android手机的关机键损坏,无法开机. 解决方法 将手机通过USB线链接电脑,进入命令行,找到adb命令所在目录,运行如下命令: adb reboot 注意:用这种方法的前提是,如果你当 ...

  3. Android 仿百合网超火爆社交app首页滑动效果

    探探,百合网等神器的首页有一个相册加载个控件,通过左滑右滑加载新的照片,同时左滑丢弃这个照片,右滑则表明对这个照片感兴趣. 这个效果是怎么实现的呢? 1,Android3.0以后控件中增加了setTr ...

  4. Swift语言学习路线图

  5. OpenCV特征点检测算法对比

    识别算法概述: SIFT/SURF基于灰度图, 一.首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点, ...

  6. JavaScript进阶(六)用JavaScript读取和保存文件

    用JavaScript读取和保存文件 因为Google还不提供同步插件数据的功能,所以导入和导出插件配置就必须和文件打交道了.而出于安全原因,只有IE才提供访问文件的API:但随着HTML 5的到来, ...

  7. 生产者消费者的java实现

    先看最简单的,也就是缓冲区的容量为1 缓冲区容量为1 import java.util.List; public class ProducerAndConsumer2 { static class A ...

  8. DB 查询分析器 6.03 如何灵活、快捷地操作国产达梦数据库

    DB 查询分析器 6.03 如何灵活.快捷地操作国产达梦数据库 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要       本文详细地介绍了"万能数据库查询分析器&qu ...

  9. vs2010修改状态栏的CStatusBar指针的的SetPaneText()方法时死活不对问题

    vs2010的mfc在有些地方不太一样不容易注意到,今天在修改状态栏的时候,就碰见了问题,死活修改不了. 参照下面的帖子: 点击打开链接 : 使用VS2010更改MFC程序的状态栏 2011-04-1 ...

  10. Nginx常用模块安装命令

    将目录切换至Nginx安装包目录下,使用./configure命令进行安装.一些第三方模块需要先下载过来,指定下解压后的目录即可. ./configure --prefix=/usr/local/ng ...