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/ ...
随机推荐
- C++ Primer 有感(异常处理)(二)
异常就是运行时出现的不正常,例如运行时耗尽了内存或遇到意外的非法输入.异常存在于程序的正常功能之外,并要求程序立即处理.不能不处理异常,异常是足够重要的,使程序不能继续正常执行的事件.如果找不到匹配的 ...
- Jquery之Bind方法参数传递与接收的三种方法
方法一. function GetCode(event) { alert(event.data.foo); } $(document).ready(function() { $("#s ...
- (NO.00001)iOS游戏SpeedBoy Lite成形记(二十二)
自己的游戏自己更需要多玩,这样才能首先发现不足的地方.所以本猫到现在已经忍一个地方很久了,就是弹出moneyLayer后每次都要输入数字才能关闭,这多少让人不爽.于是本篇我们就修正这个小小的不便. 首 ...
- react-native-android之初次相识
作为一名Android开发者,我的感觉就是,一步一卡,卡的潇洒. 但是我还是要学react-native,不要问我为什么,因为我相信一门解决了原生app,开发周期长,开发成本高,升级代价大的语言一定会 ...
- Linux用户管理命令(第二版)
添加用户 1.useradd -设置选项 用户名 [-D 查看缺省参数 ] 选项: u: UID [必须是系统中没有的] g:缺省所属用户组GID[最好有] G: 指定用户所属多个组[可以指定这个用户 ...
- AngularJS进阶(十八)在AngularJS应用中集成科大讯飞语音输入功能
在AngularJS应用中集成科大讯飞语音输入功能 注:请点击此处进行充电! 前言 根据项目需求,需要在首页搜索框中添加语音输入功能,考虑到科大讯飞语音业务的强大能力,遂决定使用科大讯飞语音输入第三方 ...
- java 编程性能调优
一.避免在循环条件中使用复杂表达式 在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快. 例子: import java.util ...
- centOS 安装(光安装 和 u盘安装)
光盘安装用这个: http://www.williamlong.info/archives/1912.html 是否保留win7,要作好相关配置.有些插件可以不装. 网络设置:不好弄 如果用u盘安装, ...
- Myexclipse创建Junit测试
. 下载JUnit的jar文件,下载地址在这里 2. 在MyEclipse中新建一个要测试的项目HelloJUnit 3. 添加一个要测试的类HelloJUnit,代码如下,注意需要先建package ...
- Sping--ApplicationEvent
//让其他的应用事件继承它 public abstract class ApplicationEvent extends EventObject { /** use serialVersionUID ...