基于C++11及std::thread实现的线程池

线程池源码:

#pragma once
#include <functional>
#include <deque>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <memory>
#include <cassert> /*
* Example:
*
* // 初始回调
* void InitCb() {
* static int i = 0;
* printf("InitCb: %d\n", i++);
* }
*
* // 任务函数
* void TaskCb() {
* static int i = 0;
* printf("TaskCb: %d\n", i++);
* }
*
* // 实例化大小为10的线程池
* std::unique_ptr<ThreadPool> upTp(new ThreadPool(10, std::bind(InitCb)));
* // 启动5个线程
* upTp->Start(5);
* do {
* // 投递任务进行处理
* upTp->InputTask(std::bind(TaskCb));
* } while(true);
*
*/
class ThreadPool
{
public:
ThreadPool(const ThreadPool& other) = delete;
ThreadPool& operator=(const ThreadPool& other) = delete;
using Task = std::function<void()>; ThreadPool(size_t max_queue_size, Task cb)
: cb_(std::move(cb)),
max_queue_size_(max_queue_size),
running_(false)
{
} ~ThreadPool()
{
if (running_)
{
Stop();
}
} void Start(unsigned num_threads)
{
assert(threads_.empty());
running_ = true;
threads_.reserve(num_threads);
for (auto i = 0; i < num_threads; ++i)
{
threads_.emplace_back(new std::thread(&ThreadPool::Process, this, i));
} if (num_threads == 0 && cb_)
{
cb_();
}
} void Stop()
{
{
std::lock_guard<std::mutex> lk(mtx_);
running_ = false;
not_empty_cond_.notify_all();
} for (auto& th : threads_)
{
th->join();
}
} void InputTask(Task task)
{
if (threads_.empty())
{
task();
}
else
{
std::unique_lock<std::mutex> lk(mtx_);
while (IsFull())
{
not_full_cond_.wait(lk);
}
assert(!IsFull()); queue_.push_back(std::move(task));
not_empty_cond_.notify_one();
}
} private:
void Process(unsigned nId)
{
printf("current thread id: %d\n", nId);
try
{
if (cb_)
{
cb_();
} while (running_)
{
Task task(Pop());
if (task)
{
task();
}
}
}
catch (...)
{
// TODO
throw;
}
} Task Pop()
{
std::unique_lock<std::mutex> lk(mtx_);
while (queue_.empty() && running_)
{
not_empty_cond_.wait(lk);
} Task task;
if (!queue_.empty())
{
task = queue_.front();
queue_.pop_front();
if (max_queue_size_ > 0)
{
not_full_cond_.notify_one();
}
}
return task;
} bool IsFull()
{
return max_queue_size_ > 0 && queue_.size() >= max_queue_size_;
} mutable std::mutex mtx_;
std::condition_variable not_empty_cond_;
std::condition_variable not_full_cond_;
Task cb_;
std::vector<std::unique_ptr<std::thread>> threads_;
std::deque<Task> queue_;
size_t max_queue_size_;
bool running_;
};

参考:陈硕——《Linux多线程服务器编程》

【C++11应用】基于C++11及std::thread实现的线程池的更多相关文章

  1. C++ 11 笔记 (五) : std::thread

    这真是一个巨大的话题.我猜记录完善绝B需要一本书的容量. 所以..我只是略有了解,等以后用的深入了再慢慢补充吧. C++写多线程真是一个痛苦的事情,当初用过C语言的CreateThread,见过boo ...

  2. C++11 多线程编程 使用lambda创建std::thread (生产/消费者模式)

    要写个tcp server / client的博客,想着先写个c++11多线程程序.方便后面写博客使用. 目前c++11中写多线程已经很方便了,不用再像之前的pthread_create,c++11中 ...

  3. Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)

    昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...

  4. C++11多线程std::thread的简单使用

    在cocos2dx 2.0时代,我们使用的是pthread库,是一套用户级线程库,被广泛地使用在跨平台应用上.但在cocos2dx 3.0中并未发现有pthread的支持文件,原来c++11中已经拥有 ...

  5. 基于C++11的100行实现简单线程池

    基于C++11的100行实现简单线程池 1 线程池原理 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小, ...

  6. C++11 并发指南------std::thread 详解

    参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...

  7. 基于C++11的线程池,简洁且可以带任意多的参数

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

  8. 基于C++11的线程池(threadpool),简洁且可以带任意多的参数

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

  9. c++11中关于`std::thread`线程传参的思考

    关于std::thread线程传参的思考 最重要要记住的一点是:参数要拷贝到线程独立内存中,不管是普通类型.还是引用类型. 对于传递参数是引用类型,需要注意: 1.当指向动态变量的指针(char *) ...

随机推荐

  1. 什么是挂载?mount的用处在哪?

    关于挂载的作用一直不是很清楚,今天在阅读教材时看见了mount这个命令,发现它的用处很隐晦但非常强大.奈何教材说的不明朗,因此在网上整合了一些优秀的解释,看完之后豁然开朗. 1.提一句Windows下 ...

  2. 在eclipse中查找一个类中的方法在其他哪个类中被调用了

    选中你所要查看的方法名,ctrl+shift+G就可以查看所有调用过该方法的地方了.在Search视图里面可以查看得到这个样子是可以的,你也可以按Ctrl+H全文检索一下

  3. codeforces gym #101161G - Binary Strings(矩阵快速幂,前缀斐波那契)

    题目链接: http://codeforces.com/gym/101161/attachments 题意: $T$组数据 每组数据包含$L,R,K$ 计算$\sum_{k|n}^{}F(n)$ 定义 ...

  4. 关于centos6版本执行程序报错:libc.so.6: version GLIBC_2.14 not found的解决

    执行后程序报错: libc.so.6: version GLIBC_2.14 not found 这种情况是因为当前服务器glibc的版本比较低造成的(不出意外是glibc_2.12是最高版本): 1 ...

  5. 记一次phoenix在不加索引的情况调优,由6s以上时间变成不到1s

    背景: 网约车预约单查询: 这里面恶心的地方是: 1个时间窗口要查询6种时间:推送订单时间(来自mongodb).有效抢单时间(来自mongodb).抢单成功时间(实时kafka).取消订单时间(实时 ...

  6. hdu5492

    hdu5492 陈大哥的毒瘤题T1 题意: 差不多就是根据题意推式子,求最小方差. 解法: 首先,可以观察到,如果我们直接暴力去取平均数,很大概率会取出来小数,所以一个很直观的想法就是把平均数从式子里 ...

  7. phpinfo中敏感信息记录

    比赛中或者渗透中如果遇到phpinfo,从里面发现的一些线索能够对后续的渗透和解题帮助很大,这里记录总结一下目前网上比较常用的的. 下图来源于:https://seaii-blog.com/index ...

  8. Nginx之 Location 的生成

    1. Location 的生成 location 的生成大致有三种: 由 location 指令直接生成 命令 location:仅用于 server 内部跳转,如 rewrite 就是命名 loca ...

  9. angcyo

    https://github.com/angcyo https://github.com/angcyo/UIKit https://github.com/angcyo/RHttpServer http ...

  10. react-native关闭所有黄色警告

    写RN经常会遇到黄色警告,很无奈,很多很多的黄色警告都是由组件自己导致的,建议在index.js 内的 AppRegistry.registerComponent('shareFile', () =& ...