#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. Spring注入

    Spring注入 Spring注入是指在启动Spring容器加载bean配置的时候,完成对变量的赋值行为. 常用的两种注入方式: setter注入 构造注入 <?xml version=&quo ...

  2. 谈谈Ext JS的组件——布局的使用方法

    概述 在Ext JS中,包含两类布局:组件类布局和容器类布局.由于有些组件是有不同的组件组合而成的,如字段就由标题和输入框构成,他们之间也是存在布局关系的,而这就需要组件类布局来处理组件内自己特有的布 ...

  3. Linux信号实践(5) --时间与定时器

    三种不同精度的睡眠 1.sleep #include <unistd.h> unsigned int sleep(unsigned int seconds); RETURN VALUE Z ...

  4. C++实现单链表

    之前一直没怎么在意C++中的链表,但是突然一下子让自己写,就老是出错.没办法,决定好好恶补一下该方面的知识,也为今后的数据结构大下个良好的基础,于是我总结出以下几点,有些地方可能不正确,还望大家不吝赐 ...

  5. linux知识汇总

    1.     利用Ctrl+Alt+F1到Ctrl+Alt+F6在6个虚拟控制台之间切换,利用Ctrl+Alt+F7切换回图形界面. 2.     使用who命令来判断谁在系统上及其登录方式.id命令 ...

  6. C++大小写转换和性能

    p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...

  7. Bootstrap 简介: 创建响应式、移动项目的工具

    原文链接: Introduction to Bootstrap: A Tool for Building Responsive, Mobile-First Projects 下载: 示例代码Boots ...

  8. 【Qt编程】Qt 小时钟

    Hello World! 学习编程语言的最简单最经典的小程序,当然Qt也不例外.在学习画图时,我觉得写个时钟小程序也是个比较好的开始.在之前的<Matlab及Java小时>一文中,我也从写 ...

  9. AngularJS进阶(十三)JS利用正则表达式校验手机号

    JS利用正则表达式校验手机号 注:请点击此处进行充电! 绪 由于项目需求,需要在前端实现手机号码的校验.当然了,对于基本的格式校验应该放在客户端进行,而不需要再将待校验的手机号发送至服务端,在服务端完 ...

  10. Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)

    ===================================================== Media Player Classic - HC 源代码分析系列文章列表: Media P ...