(原创)C++半同步半异步线程池

c++11 boost技术交流群:296561497,欢迎大家来交流技术。

线程池可以高效的处理任务,线程池中开启多个线程,等待同步队列中的任务到来,任务到来多个线程会抢着执行任务,当到来的任务太多,达到上限时需要等待片刻,任务上限保证内存不会溢出。线程池的效率和cpu核数相关,多核的话效率更高,线程数一般取cpu数量+2比较合适,否则线程过多,线程切换频繁反而会导致效率降低。

线程池有两个活动过程:1.外面不停的往线程池添加任务;2.线程池内部不停的取任务执行。活动图如下:

线程池中的队列是用的上一篇博文中的同步队列。具体代码:

 
#include<vector>
#include<thread>
#include<functional>
#include<memory>
#include <atomic>
#include"SyncQueue.hpp" const int MaxTaskCount = 100;
class ThreadPool
{
public:
using Task = std::function<void()>;
ThreadPool(int numThreads = std::thread::hardware_concurrency()) : m_queue(MaxTaskCount)
{
Start(numThreads);
} ~ThreadPool(void)
{
//如果没有停止时则主动停止线程池
Stop();
} void Stop()
{
std::call_once(m_flag, [this]{StopThreadGroup(); }); //保证多线程情况下只调用一次StopThreadGroup
} void AddTask(Task&&task)
{
m_queue.Put(std::forward<Task>(task));
} void AddTask(const Task& task)
{
m_queue.Put(task);
} private:
void Start(int numThreads)
{
m_running = true;
//创建线程组
for (int i = 0; i <numThreads; ++i)
{
m_threadgroup.push_back(std::make_shared<std::thread>(&ThreadPool::RunInThread, this));
}
} void RunInThread()
{
while (m_running)
{
//取任务分别执行
std::list<Task> list;
m_queue.Take(list); for (auto& task : list)
{
if (!m_running)
return; task();
}
}
} void StopThreadGroup()
{
m_queue.Stop(); //让同步队列中的线程停止
m_running = false; //置为false,让内部线程跳出循环并退出 for (auto thread : m_threadgroup) //等待线程结束
{
if (thread)
thread->join();
}
m_threadgroup.clear();
} std::list<std::shared_ptr<std::thread>> m_threadgroup; //处理任务的线程组
SyncQueue<Task> m_queue; //同步队列
atomic_bool m_running; //是否停止的标志
std::once_flag m_flag;
};
 

上面的代码中用到了同步队列SyncQueue,它的实现在这里。测试代码如下:

 
void TestThdPool()
{
ThreadPool pool;bool runing = true; std::thread thd1([&pool,&runing]{
while(runing)
{
cout<<"produce "<<this_thread::get_id()<< endl; pool.AddTask([]{
std::cout <<"consume "<<this_thread::get_id()<< endl;
});
}
}); this_thread::sleep_for(std::chrono::seconds(10));
runing = false;
pool.Stop(); thd1.join();
getchar();
}
 

上面的测试代码中,thd1是生产者线程,线程池内部会不断消费生产者产生的任务。在需要的时候可以提前停止线程池,只要调用Stop函数就行了。

一点梦想:尽自己一份力,让c++的世界变得更美好!

(原创)C++半同步半异步线程池2的更多相关文章

  1. 使用C++11 开发一个半同步半异步线程池

    摘自:<深入应用C++11>第九章 实际中,主要有两种方法处理大量的并发任务,一种是一个请求由系统产生一个相应的处理请求的线程(一对一) 另外一种是系统预先生成一些用于处理请求的进程,当请 ...

  2. 使用C++11实现一个半同步半异步线程池

    前言 C++11之前我们使用线程需要系统提供API.posix线程库或者使用boost提供的线程库,C++11后就加入了跨平台的线程类std::thread,线程同步相关类std::mutex.std ...

  3. c++11 实现半同步半异步线程池

    感受: 随着深入学习,现代c++给我带来越来越多的惊喜- c++真的变强大了. 半同步半异步线程池: 事实上非常好理解.分为三层 同步层:通过IO复用或者其它多线程多进程等不断的将待处理事件加入到队列 ...

  4. 分布式缓存系统 Memcached 半同步/半异步模式

    在前面工作线程初始化的分析中讲到Memcached采用典型的Master_Worker模式,也即半同步/半异步的高效网络并发模式.其中主线程(异步线程)负责接收客户端连接,然后分发给工作线程,具体由工 ...

  5. 半同步半异步模式的实现 - MSMQ实现

    半同步半异步模式的实现 - MSMQ实现 所谓半同步半异步是指,在某个方法调用中,有些代码行是同步执行方式,有些代码行是异步执行方式,下面我们来举个例子,还是以经典的PlaceOrder来说,哈哈. ...

  6. 领导者/追随者(Leader/Followers)模型和半同步/半异步(half-sync/half-async)模型都是常用的客户-服务器编程模型

    领导者-追随者(Leader/Followers)模型的比喻 半同步/半异步模型和领导者/追随者模型的区别: 半同步/半异步模型拥有一个显式的待处理事件队列,而领导者-追随者模型没有一个显式的队列(很 ...

  7. SpringBoot使用异步线程池实现生产环境批量数据推送

    前言 SpringBoot使用异步线程池: 1.编写线程池配置类,自定义一个线程池: 2.定义一个异步服务: 3.使用@Async注解指向定义的线程池: 这里以我工作中使用过的一个案例来做描述,我所在 ...

  8. spring boot:使用async异步线程池发送注册邮件(spring boot 2.3.1)

    一,为什么要使用async异步线程池? 1,在生产环境中,有一些需要延时处理的业务场景: 例如:发送电子邮件, 给手机发短信验证码 大数据量的查询统计 远程抓取数据等 这些场景占用时间较长,而用户又没 ...

  9. Spring Boot系列二 Spring @Async异步线程池用法总结

    1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncT ...

随机推荐

  1. .DS_Store文件是什么?Mac系统如何彻底清除该文件?

    用过Mac OS系统的都会注意到一个名为.DS_Store的隐藏文件,尤其是zip格式的压缩包解压的出来,会出现在各种文件夹内,非常烦人! 特别是把文件分享给使用windows的朋友的时候,这些文件会 ...

  2. virt-install创建虚拟机并制作成模板

    一.使用virt-install创建新的虚拟机 virt--template --ram --vcpu= --virt-type kvm --cdrom=/Data/kvm/iso/CentOS-.i ...

  3. 实战 MySQL 8.0.17 Clone Plugin(转)

    背景 很神奇,5.7.17 和 8.0.17,连续两个17小版本都让人眼前一亮.前者加入了组复制(Group Replication)功能,后者加入了克隆插件(Clone Plugin)功能.今天我们 ...

  4. 火鸡堂 对 基于云的胜利冲锋队 为了交项目干杯 的 Beta 产品测试报告

    基于云的胜利冲锋队 第一次上手 第一次上手体验感觉如何?能否正常运行? 不错,学生端和老师端各功能很清晰,大部分功能正常运行,但添加班级之类的部分功能页面暂时无响应 看到千帆竞发图泪流满面,图表中有各 ...

  5. 【大数据】虚拟机-Ubuntu环境

    目标 1.宿主机器能相互访问 2.虚拟机能访问互联网 方法 1.VMWare--编辑---虚拟网络编辑器,选择宿主机上网网卡 2.虚拟机设置-网络适配器 3.宿主机网络设置查看 4.Ubuntu网络设 ...

  6. css实现input文本框的双边框美化

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  7. linux学习11 Linux基础命令及命令历史

    一.Linux系统上的文件类型 1.- :常规文件:在其它程序中用f表示.比如我们用ls -l命令查看的第一个内容 [root@localhost ~]# ls -l total -rw------- ...

  8. npkill 一个方便的npm 包清理工具

    npm 包很好用,但是占用空间太多了,npkill 提供了一个方便的工具,可以帮助我们查找安装的npm 包,以及进行清理 安装 npm install -g npkill 简单使用 命令 npkill ...

  9. eclipse中的maven插件

    导入一个maven项目,一直报错:org.codehaus.plexus.archiver.jar.Manifest.write(java.io.PrintWriter)的错误 Description ...

  10. DIP大作业---图像分割

    数字图像处理课程的大作业,要求如下: 图像分割就是把图像分成若干个特定的.具有独特性质的区域并提出感兴趣目标的技术和过程.它是由图像处理到图像分析的关键步骤.现有的图像分割方法主要分以下几类:基于阈值 ...