当前位置: 首页 > news >正文

学习完C++ 并发编程后 手写线程池 最简单的线程池

目录

精简版注释:

//线程安全的队列容器(精简版)  

 最简易可行的线程池(精简版)

详细版注释:

//线程安全的队列容器(详细版) 

最简易可行的线程池(详细版)

ThreadRAII.h


参考:《C++并发编程实战 第二版》Anthony Willams著 吴天明 译

在学习完这本书后想要提高一下编码能力。

可以先参考精简版的注释,尝试写一写代码,感觉有难度的话就参考详细版。

具体代码和个人遇到的一些问题可以参考我的下一篇博客。

精简版注释:

//线程安全的队列容器(精简版)  

//实现线程安全的队列容器(通过封装一个queue)
//成员变量:
//      1.通过mutex互斥对pop、push操作加锁,从而实现“安全”
//      2.内部封装的queue,queue容器内部存储share_ptr,数据通过share_ptr间接存储好处:
//              将每个数据的share_ptr初始化放在push()中,wait_and_pop就算异常安全的
//              对share_ptr实例分配内存的操作可以脱离锁的保护,有利于增强性能
//      3.条件变量等待条件成立(pop之前必须先push)
//成员函数:
//      1.构造函数
//      2.push
//      3.pop 通过函数参数传递要pop的数据:
//              两种pop,try_pop立即返回,即使队列为空(通过返回值表示操作失败)
//              wait_and_pop 一直等到有数据才pop
//      4.通过返回值传递要pop的数据
//      5.empty
//
 

 最简易可行的线程池(精简版)

//成员变量:
//      1.监控异常的原子变量
//      2.线程安全的工作队列
//      3.工作线程
//      4.封装好的能够join线程的线程类
//      5.work_thread() 当线程池能正常工作时就一直循环执行任务

//公有成员:
//      1.构造函数
//      thread_pool():将监控异常的原子变量设置为false,
//              join_threads用工作线程vector初始化
//      {
//      }
//      2.析构函数
//      {
//       将原子变量设置为true,避免线程池销毁后,工作线程还在循环申请任务
//      }
//      3.提交线程函数(函数模板)
//      {
//              把待处理的任务(函数)提交给任务队列
//      }
//

详细版注释:

//线程安全的队列容器(详细版) 

//实现线程安全的队列容器(通过封装一个queue)
//成员变量:
//      1.通过mutex互斥对pop、push操作加锁,从而实现“安全”
//      2.内部封装的queue,queue容器内部存储share_ptr,数据通过share_ptr间接存储好处:
//              将每个数据的share_ptr初始化放在push()中,wait_and_pop就算异常安全的
//              对share_ptr实例分配内存的操作可以脱离锁的保护,有利于增强性能
//      3.条件变量等待条件成立(pop之前必须先push)
//成员函数:
//      1.构造函数
//      2.push{1.为数据创建share_ptr指针    //通过move移动操作降低开销2.互斥上锁3.队列push数据4.条件变量通知有数据}
//      3.pop 通过函数参数传递要pop的数据:
//           bool try_pop(T& value) //立即返回,即使队列为空(通过返回值表示操作失败){    //pop操作都是要操作队列的,所以一开始就要上锁,没有操作能提取到互斥之外1.互斥上锁2.判断是否为空队列 if(空) return false;else(不空) {1.队头数据传给value    //通过move移动操作降低开销2.队列pop3.return true;}}
//            void wait_and_pop(T& value) //一直等到有数据才pop{    //pop操作都是要操作队列的,所以一开始就要上锁,没有操作能提取到互斥之外1.互斥上锁;2.通过条件变量等待条件发生,通过lambda表达式保证即使被条件变量唤醒了,也要保证队列非空才能进行pop操作;3.对头数据传给value;4.队列pop               }
//      4.通过返回值传递要pop的数据:std::shared_ptr<T> try_pop(){    //pop操作都是要操作队列的,所以一开始就要上锁,没有操作能提取到互斥之外1.互斥上锁;2.判断是否为空队列 if(空) return nullptr;else(不空){1.临时变量取得队头数据2.队列pop3.return 临时变量}}std::shared_ptr<T> wait_and_pop(){    //pop操作都是要操作队列的,所以一开始就要上锁,没有操作能提取到互斥之外1.互斥上锁2.通过条件等待条件发生,通过lambda表达式保证即使被条件变量唤醒了,也要保证队列非空才能进行pop操作;3.临时变量取得对头数据4.队列pop5.return 临时变量}
//      5. bool empty() const{    //函数声明为const 要求将mutex 声明为mutable1.互斥上锁2.返回 封装队列的empty();}
//

最简易可行的线程池(详细版)

#ifndef _THREAD_POOL_EASY_HPP_
#define _THREAD_POOL_EASY_HPP_
#include "ThreadRAII" //join_threads
#include "threadsafe_queue"    //   
//最简单的线程池::工作线程数目固定,当有任务要处理时就把他放进任务队列
//所以需要一个任务队列,用threadsafe_queue来实现
//各线程从任务队列中领取任务
//工作线程存储在vector容器中,并被引用到join_threads中,进行统一的析构管理
//
//私有成员:
//      1.线程的启动可能抛出异常,所以需要一个原子变量进行标识,
//      当该变量false时,线程池正常工作
//              每当有异常抛出时,设置为true 
//              线程池析构时,也设置为true,
//              保证线程池析构后工作线程不会继续循环尝试从工作队列中获取任务
//      2.线程安全的工作队列
//      3.使用vector容器存放工作线程
//      4.封装好的能够join线程的线程类join_threads 里面存的是工作线程vector的整个引用 
//      5.work_thread() 当线程池能正常工作时就一直循环执行任务
//              {
//                      while(线程池正常工作)
//                      {
//                              临时变量用来接收任务
//                              if(工作队列能pop出任务)
//                                      执行任务;
//                              else 
//                                      将cpu时间让给其他线程;
//                      }
//              }
//公有成员:
//      1.构造函数
//      thread_pool():将监控异常的原子变量设置为false,
//              join_threads用工作线程vector初始化
//      {
//              通过std::thread::hardware_concurrency()取得最大线程数
//              try
//              { //线程启动可能抛出异常,所以用try catch包住
//                      for(最大线程数)
//                      {
//                              工作线程放到存放工作线程的vector里
//                      }
//              }
//              catch(...){
//                      出现异常将原子变量设置为true;
//                      throw;
//              }
//      }
//      2.析构函数
//      {
//       将原子变量设置为true,避免线程池销毁后,工作线程还在循环申请任务
//      }
//      3.提交线程函数(函数模板)
//      {
//              把待处理的任务(函数)提交给任务队列
//      }
//#endif

ThreadRAII.h

还需要封装thread类,使std::thread对象在所有路径皆不可联结:详细请参考本书第八章或effective modren C++ 条款37

#ifndef _THREADRAII_H_
#define _THREADRAII_H_//通过封装thread类,使std::thread对象在所有路径皆不可联结
// 详细参见 effective modren C++ 条款37
#include <vector>
#include <thread>
class join_threads
{private:std::vector<std::thread>& threads;public:explicit join_threads(std::vector<std::thread>& threads_):threads(threads_) {}~join_threads(){for(unsigned long i =0; i<threads.size(); i++){if(threads[i].joinable()){threads[i].join();}else{threads[i].detach();}}}
};
#endif

相关文章:

学习完C++ 并发编程后 手写线程池 最简单的线程池

目录 精简版注释&#xff1a; //线程安全的队列容器&#xff08;精简版&#xff09; 最简易可行的线程池&#xff08;精简版&#xff09; 详细版注释&#xff1a; //线程安全的队列容器&#xff08;详细版&#xff09; 最简易可行的线程池&#xff08;详细版&#xff0…...

【Overload游戏引擎分析】编辑器对象鼠标拾取原理

Overload的场景视图区有拾取鼠标功能&#xff0c;单击拾取物体后会显示在Inspector面板中。本文来分析鼠标拾取这个功能背后的原理。 一、OpenGL的FrameBuffer 实现鼠标拾取常用的方式有两种&#xff1a;渲染id到纹理、光线投射求交。Overload使用的是渲染id到纹理&#xff0c…...

【Spring内容进阶 | 第三篇】AOP进阶内容

前言&#xff1a; 在前面我们已经粗略的介绍了什么是AOP以及各种基础知识点&#xff0c;而本篇我们将聚焦于AOP的细节&#xff0c;详细的讲解一下AOP中的通知类型&#xff0c;通知顺序&#xff0c;切入点表达式以及连接点。通过对AOP的熟练掌握&#xff0c;我们可以快速编写出低…...

华为云ModelArts:引领AI艺术创作的未来,让人人都可以成为“艺术家”!

随着科技的飞速发展,艺术创作逐渐告别传统的画布和画笔,开始走向数字化、智能化的新时代。在这个蓬勃发展的领域中,华为云ModelArts以其强大的功能和出色的性能引领着AI艺术创作的未来。 华为云ModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处…...

Elasticsearch:如何从 Elasticsearch 集群中删除数据节点

Elasticsearch 集群通常包含多个节点&#xff0c;并且可能存在需要从集群中删除节点的情况。 应谨慎执行此过程&#xff0c;以确保数据的完整性和可用性。 在本文中&#xff0c;我们将引导你完成从 Elasticsearch 集群安全删除节点的步骤。 确保集群是绿色的 在尝试从 Elastic…...

长假回归,回顾一下所有的电商API接口

淘宝API接口 item_get 获得淘宝商品详情item_get_pro 获得淘宝商品详情高级版item_review 获得淘宝商品评论 获取测试keyitem_fee 获得淘宝商品快递费用item_password 获得淘口令真实urlitem_list_updown 批量获得淘宝商品上下架时间seller_info 获得淘宝店铺详情item_search…...

认识计算机主板

目录 定义主要部件简单图示 主要功能 定义 计算机主板&#xff08;Motherboard&#xff09;是计算机系统中的核心组件之一&#xff0c;也被称为系统板、主板或母板。它是一个电子电路板&#xff0c;用于连接和支持计算机的各种硬件组件&#xff0c;包括中央处理器&#xff08;…...

PHP乱七八糟面试题

1、请解释PHP中的JWT是什么&#xff1f; JWT&#xff08;JSON Web Token&#xff09;是一种用于认证和授权的标准&#xff0c;可以在不同的系统之间安全地传递信息。 在PHP中&#xff0c;可以使用各种JWT库来生成和解析JWT&#xff0c;JWT包含了一些元数据和签名&#xff0c; …...

pom管理规范

0. 引言 在单机架构下&#xff0c;我们只需要将我们的依赖在pom中引入。但是过渡到微服务架构后&#xff0c;会涉及到多模块引用相同的依赖&#xff0c;多模版之间依赖的版本太过分散难以管理的问题。 这就需要我们利用maven中依赖传递的特性&#xff0c;结合dependencyManage…...

AI大模型的安全隐患问题与新兴Anthropic新势力涌动

引言&#xff1a; 无论从社会层面或技术层面&#xff0c;大模型的安全隐患都是一个不容小觑的话题。也正因此&#xff0c;ChatGPT 初兴起时&#xff0c;国内的 To C 大模型产品一时受阻。而尽管 9 月初第一批 8 家大模型通过备案&#xff0c;各家厂商对大模型的安全问题也不敢…...

slamplay:用C++实现的SLAM工具集

0. 项目简介 slamplay 是一个功能强大的工具集合&#xff0c;可用于开始使用 C 来玩和试验 SLAM。这是一项正在进行的工作。它在单个 cmake 框架中安装并提供一些最重要的功能 后端框架&#xff08;g2o、gtsam、ceres、se-sync 等&#xff09;、 前端工具&#xff08;opencv、…...

IPT2602协议-USB 快速充电端口控制器

产品描述&#xff1a; IPT2602是一款USB端口快速充电协议控制芯片。IPT2602智能识别多种快速充电协议&#xff0c;对手机等受电设备进行快速充电。IPT2602根据受电设备发送的电压请求能够精确的调整VBUS输出电压&#xff0c;从而实现快速充电。 IPT2602在调整5V输出电压前会自动…...

Zotero 超好用插件的下载链接及配置方法(PDF-translate/ZotFile/茉莉花/Zotero Scihub)

目录 前言插件安装方法插件一&#xff1a;文献翻译插件&#xff08;pdf-translate&#xff09;插件二&#xff1a;文献附件管理&#xff08;ZotFile&#xff09;插件三&#xff1a;中文文献插件&#xff08;茉莉花&#xff09;插件四&#xff1a;Sci-Hub 自动下载文献&#xff…...

Titus网关中的缓存一致性机制

API网关引入缓存可以在不影响数据一致性的前提下&#xff0c;有效优化接口时延。本文介绍了Netflix在Titus网关上引入缓存的实践&#xff0c;比较了有无缓存对访问时延的影响。原文: Consistent caching mechanism in Titus Gateway 前言 Titus是Netflix的云容器运行时&#xf…...

flutter开发实战 - inappwebview设置cookie

flutter开发实战-inappwebview设置cookie 在使用inappwebview时候&#xff0c;需要设置cookie&#xff0c;这里记录一下 一、在initialUserScripts中设置cookie 在inappwebview中有一个initialUserScripts&#xff0c;可以初始化设置cookie等&#xff0c;我们可以通过该属性…...

零基础如何自学网络安全,基于就业前景全方位讲解,包教包会

你是否对网络空间安全充满好奇&#xff1f;想要解开网络世界神秘的面纱&#xff1f;你是否对黑客技术着迷&#xff1f;而找不到合适的学习途径&#xff1f;你是否遭到过各种各样的网络攻击&#xff0c;却因知识的匮乏束手无策&#xff1f; 那么接下来将为你全面介绍&#xff0c…...

Java项目防止SQL注入的几种方案

目录 一、什么是SQL注入&#xff1f; 二、Java项目防止SQL注入方式 1、PreparedStatement防止SQL注入 2、mybatis中#{}防止SQL注入 3、对请求参数的敏感词汇进行过滤 4、nginx反向代理防止SQL注入 一、什么是SQL注入&#xff1f; SQL注入即是指web应用程序对用户输入数…...

Win11 安装安卓子系统方法教程

WIN11安装安卓子系统 准备工作下载安装安装完成使用adb连接子系统结束 准备工作 开启电脑中的 控制面板>>>>程序和功能>>启用或关闭Windows功能>>>找到“Hyper-V”&#xff0c;把勾都勾上&#xff0c;确定&#xff0c;完成安装&#xff0c;并重启电…...

golang pg 数据库不存在 就创建 --chatPGT

问&#xff1a;linkOrCreateDatabase(addr ), 函数执行 连接 pg数据库&#xff0c;若数据库 不存在就创建 gpt: 要在 Go 中连接到 PostgreSQL 数据库并在数据库不存在时创建数据库&#xff0c;你可以使用 github.com/lib/pq 包以及 database/sql 包。以下是一个示例&#xff1…...

VUE3照本宣科——eslint与prettier

VUE3照本宣科——eslint与prettier VUE3照本宣科系列导航 前言一、eslint1.配置文件2.配置规则3.忽略错误 二、prettier三、总结 VUE3照本宣科系列导航 1.VUE3照本宣科——认识VUE3 2.VUE3照本宣科——应用实例API与setup 3.VUE3照本宣科——响应式与生命周期钩子 4.VUE3照本宣…...

PyCharm专业版SSH远程开发环境一站式部署指南

1. PyCharm专业版安装与激活 作为数据科学和算法开发的主力工具&#xff0c;PyCharm专业版提供了完整的远程开发支持。首先需要从JetBrains官网下载对应操作系统的安装包。这里有个小技巧&#xff1a;如果你使用的是Windows系统但需要连接Linux服务器开发&#xff0c;建议选择W…...

网盘下载革命:LinkSwift 如何让你在9大平台轻松获取真实下载地址

网盘下载革命&#xff1a;LinkSwift 如何让你在9大平台轻松获取真实下载地址 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云…...

5分钟快速上手Sonar CNES Report:让代码质量报告变得简单高效

5分钟快速上手Sonar CNES Report&#xff1a;让代码质量报告变得简单高效 【免费下载链接】sonar-cnes-report Generates analysis reports from SonarQube web API. 项目地址: https://gitcode.com/gh_mirrors/so/sonar-cnes-report 你是否经历过这样的场景&#xff1f…...

AI 搜索重新重视来源:内容平台的新机会不是被点击,而是被正确引用

生成式搜索刚出现时&#xff0c;很多内容创作者最担心的问题是&#xff1a;如果答案直接出现在搜索页&#xff0c;用户还会不会点进原文&#xff1f;这个担心并不多余。AI Overviews、AI Mode 和各类答案引擎&#xff0c;确实改变了“搜索结果页到网页”的传统路径。但现在更值…...

构建AI信任层TrustLayer:开源插件化架构保障AI输出安全与可靠

1. 项目概述&#xff1a;为什么我们需要一个AI信任层&#xff1f;最近几个月&#xff0c;我几乎把所有主流的AI工具都试了个遍。从代码助手到文案生成&#xff0c;从图像创作到数据分析&#xff0c;每个工具都承诺能提升效率。但用着用着&#xff0c;我发现一个越来越明显的问题…...

Windows安卓应用安装器:快速轻量级解决方案终极指南

Windows安卓应用安装器&#xff1a;快速轻量级解决方案终极指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 想在Windows电脑上轻松安装安卓应用吗&#xff1f;厌倦…...

从图形变换到机器学习:行列式到底在‘衡量’什么?一个直观的几何理解指南

从图形变换到机器学习&#xff1a;行列式到底在‘衡量’什么&#xff1f;一个直观的几何理解指南 想象你手中有一张弹性薄膜&#xff0c;拉伸、旋转或挤压它时&#xff0c;薄膜覆盖的面积会如何变化&#xff1f;这种直观的几何变换背后&#xff0c;隐藏着线性代数中行列式的本质…...

如何在5分钟内配置鸣潮自动化助手,实现多账号高效管理?

如何在5分钟内配置鸣潮自动化助手&#xff0c;实现多账号高效管理&#xff1f; 【免费下载链接】better-wuthering-waves &#x1f30a;更好的鸣潮 - 后台自动剧情 项目地址: https://gitcode.com/gh_mirrors/be/better-wuthering-waves 厌倦了《鸣潮》中重复的剧情对话…...

Pinecone示例库实战指南:从向量数据库原理到RAG应用开发

1. 项目概述&#xff1a;Pinecone示例库的深度探索 如果你正在寻找一个能让你快速上手向量数据库和现代AI应用开发的“实战训练营”&#xff0c;那么Pinecone官方的 pinecone-io/examples 仓库绝对是一个不容错过的宝藏。这个仓库远不止是一个简单的代码合集&#xff0c;它更…...

2026出海技术观察:云API接口迭代的能力边界与业务增量空间

摘要&#xff1a;2026年AI出海告别粗放扩张&#xff0c;底层技术适配能力成为竞争核心。云API接口迭代持续优化跨境对接、算力调度与合规适配体系&#xff0c;补齐传统出海技术短板&#xff0c;为企业全球化精细化运营提供坚实支撑。一、2026 AI出海新格局&#xff1a;底层接口…...