C++11 线程池:轻量级高并发解决方案

C++11 线程池:轻量级高并发解决方案

线程池(Thread Pool)是一种线程管理的机制,它包含了多个预先创建的线程,用于执行多个任务,这些任务被放入任务队列中等待执行。

满足我们的生产者和消费者模型。
在这里插入图片描述

线程池的核心组成部分。
  • 任务队列 -----按顺序等待要处理的任务。
  • 线程数组----- 多个已启动的线程,从任务队列拿取任务处理。
  • 互斥锁。
  • 条件变量。
  • 任务。
线程池的好处:
  • 减少线程的创建和销毁次数,提高系统的性能和效率。因为我们每次创建和销毁线程都是有开销的。
  • 活动的线程需要消耗系统资源,如果启动太多,会导致系统由于过度消耗内存或切换过度而导致系统资源不足。
  • 通过重复利用已创建的线程 ,避免了频繁创建和销毁线程的性能开销。

基于C++11实现的线程池:感受C++11的魅力

当然实际项目中的线程池可能会更复杂。但是对于初学者 ,你能够了解到这里已经足够了。

ThreadPool.h 线程池必要的接口 ,和属性。
#ifndef _THREAD_POOL_H_
#define _THREAD_POOL_H_#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <queue>
#include <functional>class ThreadPool {
public:// 创建线程池单例static ThreadPool* getIntance(int num) {static ThreadPool* threadPool = nullptr;// call_once()   ,保证函数只能执行一次 ,只能在多线程里面使用std::call_once(flag_, init_threadPool, threadPool, num);return threadPool;}// 往线程池中添任务template <typename F , typename...  Agrs>void push_task(F &&f , Agrs&&...  agrs);private:static void init_threadPool(ThreadPool*& p, int num) {p = new ThreadPool(num);}ThreadPool(int num = 4);   // 默认线程数是 4 ~ThreadPool();std::queue<std::function<void()>>task_queue_;   // 任务队列std::vector<std::thread>threads;              // 线程数组std::mutex mutex_;   // 互斥锁std::condition_variable c_variable_;  // 条件变量bool isStop_;        // 线程池是否终止static std::once_flag flag_;    // call_once()  需要的flag
};// 往任务队列添加任务
template <typename F, typename...  Agrs>
void ThreadPool::push_task(F&& f, Agrs&&...  agrs) {// 将函数和参数进行绑定// forward 实现完美转换std::function<void()>task = std::bind(std::forward<F>(f), std::forward<Agrs>(agrs)...);{std::unique_lock<std::mutex>lock(mutex_);// 加入任务队列task_queue_.emplace(task);}c_variable_.notify_one();   // 唤醒一个线程来执行
}#endif // !_THREAD_POOL_H
ThreadPool.cpp 相关接口的具体实现。
#include "ThreadPool.h"std::once_flag ThreadPool::flag_;ThreadPool::ThreadPool(int num):isStop_ ( false ) {for (int i = 0; i < num ; i++) {threads.emplace_back([this]( ) {while ( true ) {std::unique_lock<std::mutex>lock(mutex_);c_variable_.wait(lock, [ = ]() {return (!task_queue_.empty() || isStop_);});if ( isStop_  && task_queue_.empty() ) {  // 如果被线程池终止了return;}std::cout << "线程池处理" << std::endl;// 从任务队列,拿出任务执行std::function<void( )>task(std::move(task_queue_.front()));task_queue_.pop();task();}});}
}ThreadPool::~ThreadPool( ) {{std::unique_lock<std::mutex>lock(mutex_);isStop_ = true;if (!task_queue_.empty())   c_variable_.notify_all();   // 唤醒所有线程去执行任务}for ( auto& a : threads ) {a.join();}
}
测试代码:
#include "ThreadPool.h"
#include <iostream>
#include <algorithm>
#include <chrono>void print(const char *name) {std::cout << "name :" << name << std::endl;
}int getMax(int a, int b) {return std::max(a, b);
}void sort(std::vector<int>*&value) {// 默认是升序std::sort(value->begin(), value->end());   // 
}int main() {// 创建一个线程池 ,线程数为4ThreadPool *pool = ThreadPool::getIntance( 4 );std::vector<int>value;//for (int i = 1; i < 10; i++) {//	pool->push_task( [i]() {//		std::cout << "task runing " << i << std::endl;//		std::this_thread::sleep_for(std::chrono::seconds(1)); // 休眠1秒//		std::cout << "task stop : " << i << std::endl;//		});//}for (int i = 10; i > 0; i--) {value.emplace_back(i);}// 将任务投入线程池,让线程来处理pool->push_task(print, "小美");   // 输出小美pool->push_task(sort, &value);   // 升序排序std::this_thread::sleep_for(std::chrono::seconds(10)); // 休眠10秒for (int i = 0; i < value.size(); i++) {std::cout << value[i] << std::endl;}std::cout << "\n";return 0;
}
测试结果:

在这里插入图片描述

效果达到预期 ,当然你也可以多写几个测试案例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/11985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文带你快速了解GPT-4o!内含免费使用指南!

一、GPT-4o简介 北京时间5月14日&#xff0c;OpenAI举行春季发布会。OpenAI在活动中发布了新旗舰模型“GPT-4o”&#xff01;据OpenAI首席技术官穆里穆拉蒂&#xff08;Muri Murati&#xff09;介绍&#xff0c;GPT-4o在继承GPT-4强大智能的同时&#xff0c;进一步提升了文本、…

电力场景设备漏油检测数据集VOC+YOLO格式338张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;338 标注数量(xml文件个数)&#xff1a;338 标注数量(txt文件个数)&#xff1a;338 标注类别…

Qt---项目的创建及运行

一、创建第一个Qt程序 1. 点击创建项目后&#xff0c;选择项目路径以及给项目起名称 名称&#xff1a;不能有中文、不能有空格 路径&#xff1a;不能有中文路径 2. 默认创建有窗口类myWidget&#xff0c;基类有三种选择&#xff1a;QWidget、QMainWindow、QDialog 3. m…

#自学习# 记一次py脚本打开浏览器页面

在项目总结中&#xff0c;遇到系统后台利用浏览器拉起一个已知路径页面的需求&#xff0c;趁着机会整理下。实现起来比较简单&#xff0c;浏览器默认谷歌。 一、技术原理 Selenium&#xff1a;Selenium 是一个用于自动化 Web 浏览器的工具&#xff0c;可模拟用户在浏览器中的各…

成都百洲文化传媒有限公司怎么样?靠谱吗?

在数字化浪潮席卷全球的今天&#xff0c;电商行业正以前所未有的速度蓬勃发展。作为这一变革的积极参与者和推动者&#xff0c;成都百洲文化传媒有限公司以其专业的电商服务&#xff0c;正逐渐成为行业内的佼佼者。 一、公司简介 成都百洲文化传媒有限公司自成立以来&#xff…

MyBatis的创建和测试

创建项目点击Spring Initializr然后点击next 点击SQL 选择里面的Mybatis Framework和Mysql Driver 按如下图片创建项目 user表中的数据 #下面这些内容是为了让MyBatis映射 #指定Mybatis的Mapper文件 mybatis.mapper-locationsclasspath:mappers/*xml #指定Mybatis的实体目录 my…

【Java】IDEA自动生成类图和时序图

【Java】IDEA自动生成类图和时序图 idea 的强大之处在于此&#xff0c;它包含了很多小插件&#xff0c;我们不需要再次下载相关插件&#xff0c;只需要在idea中小小的设置一下就可以了,下面是设置方法&#xff0c;我用的是idea2020版本 打开设置File -> Settings->Diagr…

Netty-面试题(中)(五十)

关于零拷贝和堆外内存 Java在将数据发送出去的时候&#xff0c;会先将数据从堆内存拷贝到堆外内存&#xff0c;然后才会将堆外内存再拷贝到内核态&#xff0c;进行消息的收发&#xff0c;代码如下: 所以&#xff0c;我们发现&#xff0c;假如我们在收发报文的时候使用直接内存&…

【Linux】进程信号(2万字)

目录 前言 一、生活角度的信号 1.1、我们来见一见信号&#xff1a; 1.2、模拟一下 kill 指令 二、信号的处理 三、产生信号的5种方法 3.1、kill命令 3.2、键盘可以产生信号 3.3、3种系统调用 3.4、软件条件 3.5、异常 四、比较 core 和 Term 五、键盘信号产生 六…

SSL/TLS协议信息泄露漏洞(CVE-2016-2183)解法

1.运行gpedit.msc&#xff0c;进入本地组策略编辑器。 2. 本地组策略编辑器-->计算机配置-->管理模板-->网络-->SSL配置设置-->启用“SSL密码套件顺序”。 3. 将原有的密码套件值清空&#xff0c;拷入下面的值&#xff0c;保存设置&#xff0c;并重启服务器即…

EmotiVoice 实时语音合成TTS;api接口远程调用

参考:https://github.com/netease-youdao/EmotiVoice 测试整体速度可以 docker安装: 运行容器:默认运行了两个服务,8501 一个streamlit页面,另外8000是一个api接口服务 docker run -dp 8501:8501 -p 8250:8000 syq163/emoti-voice:latest##gpu运行 (gpu运行遇到CUDA er…

ios与android上音频格式的推荐

首先贴一张官方对于ios与android上音频格式的推荐&#xff1a; 这里只给出了推荐格式&#xff0c;一般我们在实际运用中会使用如下方式&#xff1a; 一、IOS与安卓各一套&#xff1a;音乐&#xff1a;都使用MP3 音效&#xff1a;ios用caf Android用ogg 二、使用通用的MP3格式…

【Linux系统编程】第十八弹---进程状态(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、操作系统进程 1.1、进程背景 1.2、进程如何在CPU上运行的&#xff1f; 1.2、进程状态 2、Linux的进程状态 2.1、如何描…

Linux修炼之路之权限

目录 引言 一&#xff1a;Linux中用户的分类 二&#xff1a;在Linux中的权限 1.权限的两种属性 1.人的属性 2.事物属性 -主要以文件属性为主 3.文件权限值的两种表示方式方法 2.更改文件访问者(拥有者&#xff0c;所属组&#xff0c;其他人)权限属性 3.更改文件的拥有…

commvault学习(7):恢复oracle

在实际生产环境中&#xff0c;oracle的恢复方式大部分是异机恢复。 环境&#xff1a; 备份机&#xff1a;windows server2008&#xff0c;ip&#xff1a;192.168.20.56 恢复目标机&#xff1a;windows server2008&#xff0c;ip&#xff1a;192.168.20.55 CS、MA&#xff1…

建立一物一码数字化营销体系,纳宝科技助力五丰黎红在调味品行业再创佳绩!

五丰黎红隶属于华润五丰集团&#xff0c;公司历史可溯源至1979年&#xff0c;前身是汉源花椒油厂&#xff0c;是一家拥有悠久历史的调味品品牌。一直以来&#xff0c;五丰黎红坚持调味品原料、研发、生产、加工一体化的全产业链经营模式&#xff0c;以“质量”为核心&#xff0…

[FlareOn1]Bob Doge

[FlareOn1]Bob Doge Hint:本题解出相应字符串后请用flag{}包裹&#xff0c;形如&#xff1a;flag{123456flare-on.com} 得到的 flag 请包上 flag{} 提交。 密码&#xff1a;malware 没什么思路&#xff0c;原exe文件运行又install了一个challenge1.exe文件 c#写的&#xff…

windows vscode设置扩展和缓存目录

vscode的扩展和缓存占了很大的空间&#xff0c;而且默认在C盘&#xff0c;很烦。。。 修改vscode快捷方式的目标处&#xff1a;"C:\Users\Nv9\AppData\Local\Programs\Microsoft VS Code\Code.exe" --extensions-dir "D:\Program Cache\VScode\extensions"…

基础模型的推理:综述

24年1月论文“A Survey of Reasoning with Foundation Models”&#xff0c;来自香港中文大学、华为、香港大学、上海AI实验室、香港科技大学、大连理工、北京大学、清华大学、合肥工大、中国人民大学、复旦大学和香港科技大学广州分校。 推理是解决复杂问题的关键能力&#x…

网上跳蚤市场|基于SSM+vue的网上跳蚤市场系统的设计与实现(源码+数据库+文档)

网上跳蚤市场系统 目录 基于SSM&#xff0b;vue的网上跳蚤市场系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台登录模块 5.2.1管理员功能 5.2.2会员功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…