高阶开发基础——快速入门C++并发编程6——大作业:实现一个超级迷你的线程池
目录
实现一个无返回的线程池
完全代码实现
Reference
实现一个无返回的线程池
实现一个简单的线程池非常简单,我们首先聊一聊线程池的定义:
线程池(Thread Pool) 是一种并发编程的设计模式,用于管理和复用多个线程,以提高程序的性能和资源利用率。它的核心思想是预先创建一组线程,并将任务分配给这些线程执行,而不是为每个任务单独创建和销毁线程。线程池广泛应用于需要处理大量短期任务的场景,例如 Web 服务器、数据库连接池、任务调度系统等。换而言之,线程池说白了就是一种饿汉思维——直接预先提供若干的线程,由线程池内部控制调度,确保我们可以只关心任务的提交以及完成。
我们下面要做的是设计一个任务是不返回的线程池。所以,我们约束我们的函数是:
using supportive_task_type = std::function<void()>;
下一步,就是构造我们的线程池的线程。注意的是——线程和任务是解耦合的,意味着我们需要一个中间函数解耦合任务派发。笔者决定,将任务派发分到一个私有函数完成:
CCThreadPool(const int workers_num) {for(int i = 0; i < workers_num; i++){internal_threads.emplace_back([this](){__scheduled();});}}
上面这个代码很简单,就是将每一个线程都分配一个调度函数,这个调度函数来委派分发任务,办法说简单也很简单:
void __scheduled(){while(1){// sources protectionsstd::unique_lock<std::mutex> locker(internal_mutex);// waiting for the access of the task resourcescontrolling_cv.wait(locker, [this]{return thread_pool_status || !tasks_queue.empty();});// quit if requriedif(thread_pool_status && tasks_queue.empty()){return;}// 现在我们可以取到任务执行了supportive_task_type task(std::move(tasks_queue.front()));tasks_queue.pop();locker.unlock();task();}}
当析构的时候,我们也要通知所有线程的cv不要睡眠了,由于设置了thread_pool_status
是true,直接线程跳出来结束全文。
~CCThreadPool(){thread_pool_status = true;controlling_cv.notify_all();for(auto& thread : internal_threads){thread.join();}}
完全代码实现
#include <condition_variable>
#include <functional>
#include <mutex>
#include <print>
#include <queue>
#include <thread>
#include <utility>
#include <vector>
class CCThreadPool {public:CCThreadPool() = delete;CCThreadPool(const CCThreadPool &) = delete;CCThreadPool &operator=(CCThreadPool &) = delete;
CCThreadPool(const int workers_num) {for(int i = 0; i < workers_num; i++){internal_threads.emplace_back([this](){__scheduled();});}}
~CCThreadPool(){thread_pool_status = true;controlling_cv.notify_all();for(auto& thread : internal_threads){thread.join();}}
template<typename F, typename... Args>void enTask(F&& f, Args&&... args){supportive_task_type task(std::bind(std::forward<F&&>(f), std::forward<Args&&>(args)...));{std::unique_lock<std::mutex> locker(internal_mutex);tasks_queue.emplace(std::move(task));}controlling_cv.notify_one();}
private:void __scheduled(){while(1){std::unique_lock<std::mutex> locker(internal_mutex);controlling_cv.wait(locker, [this]{return thread_pool_status || !tasks_queue.empty();});// quitif(thread_pool_status && tasks_queue.empty()){return;}supportive_task_type task(std::move(tasks_queue.front()));tasks_queue.pop();locker.unlock();task();}}
using supportive_task_type = std::function<void()>;std::vector<std::thread> internal_threads;std::queue<supportive_task_type> tasks_queue;std::mutex internal_mutex;std::condition_variable controlling_cv;bool thread_pool_status = false;
};
int main()
{std::println("Task start");CCThreadPool pool(4);for (int i = 0; i < 8; ++i) {pool.enTask([i] {std::println("Task {} is started at thread with id {}", i, std::this_thread::get_id());std::this_thread::sleep_for(std::chrono::seconds(1));std::println("Task {} is done", i);});}return 0;
}
Reference
8. C++11 跨平台线程池-See的编程日记 (seestudy.cn)
相关文章:
高阶开发基础——快速入门C++并发编程6——大作业:实现一个超级迷你的线程池
目录 实现一个无返回的线程池 完全代码实现 Reference 实现一个无返回的线程池 实现一个简单的线程池非常简单,我们首先聊一聊线程池的定义: 线程池(Thread Pool) 是一种并发编程的设计模式,用于管理和复用多个线程…...
deep generative model stanford lecture note3 --- latent variable
1 Introduction 自回归模型随着gpt的出现取得很大的成功,还是有很多工程上的问题并不是很适合使用自回归模型: 1)自回归需要的算力太大,满足不了实时性要求:例如在自动驾驶的轨迹预测任务中,如果要用纯自回…...
【PDF提取局部内容改名】批量获取PDF局部文字内容改名 基于QT和百度云api的完整实现方案
应用场景 1. 档案管理 在企业或机构的档案管理中,常常会有大量的 PDF 格式的文件,如合同、报告、发票等。这些文件的原始文件名可能没有明确的标识,不利于查找和管理。通过批量获取 PDF 局部文字内容并改名,可以根据文件中的关键信息(如合同编号、报告标题等)为文件重新…...
吴恩达深度学习——卷积神经网络基础
本文来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习所用。 文章目录 矩阵和张量边缘检测计算方式检测原理 Valid卷积和Same卷积卷积步长三维卷积单层卷积网络总结符号定义输入输出维度其他参数维度 举例 池化层示例输入层第一层卷积 - 池化第二层卷…...
MySQL锁详解
MySQL锁详解 数据库的锁机制锁的分类行级锁与表级锁行级锁之共享锁与排他锁乐观锁与悲观锁悲观锁乐观锁 Innodb存储引擎的锁机制行级锁与表级锁的使用区分三种行锁的算法死锁的问题多版本并发控制MVCC 数据库的锁机制 什么是锁?锁是一种保障数据的机制 为何要用锁…...
快速提升网站收录:利用网站用户反馈机制
本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/59.html 利用网站用户反馈机制是快速提升网站收录的有效策略之一。以下是一些具体的实施步骤和建议: 一、建立用户反馈机制 多样化反馈渠道: 设立在线反馈表、邮件…...
初五,很棒
20元一瓶的水见过没?配料只有水和维C,养生佳品?除非我疯了。 今晚和大姨爹等人探讨成家问题。没错,我变成最应该成家的人了。 的确,从年龄上,发展阶段上,也是应该成家啦。 难道我不知道嘛。 人…...
Vue指令v-html
目录 一、Vue中的v-html指令是什么?二、v-html指令与v-text指令的区别? 一、Vue中的v-html指令是什么? v-html指令的作用是:设置元素的innerHTML,内容中有html结构会被解析为标签。 二、v-html指令与v-text指令的区别…...
ubuntu磁盘扩容
ubuntu磁盘扩容 描述先在虚拟机设置里面扩容进入Ubuntu 配置使用命令行工具parted进行分区输出如下完成 描述 执行命令,查看 fs 类型是什么 lsblk -o NAME,FSTYPE,MOUNTPOINT将60G扩容到100G,其中有些操作我也不知道什么意思,反正就是成功了࿰…...
BFS(广度优先搜索)——搜索算法
BFS,也就是广度(宽度)优先搜索,二叉树的层序遍历就是一个BFS的过程。而前、中、后序遍历则是DFS(深度优先搜索)。从字面意思也很好理解,DFS就是一条路走到黑,BFS则是一层一层地展开。…...
SAP SD学习笔记27 - 请求计划(开票计划)之1 - 定期请求(定期开票)
上两章讲了贩卖契约(框架协议)的概要,以及贩卖契约中最为常用的 基本契约 - 数量契约和金额契约。 SAP SD学习笔记26 - 贩卖契约(框架协议)的概要,基本契约 - 数量契约_sap 框架协议-CSDN博客 SAP SD学习笔记27 - 贩卖契约(框架…...
string例题
一、字符串最后一个单词长度 题目解析:由题输入一段字符串或一句话找最后一个单词的长度,也就是找最后一个空格后的单词长度。1.既然有空格那用我们常规的cin就不行了,我们这里使用getline,2.读取空格既然是最后一个空格后的单词,…...
Revit二次开发 自适应族添加放样融合
大多数博客给出的方案都是如何在有自适应族的情况下进行修改定位点或是将数据传入自适应族,如何直接在族文件中创建自适应模型并将点转换为自适应点,连接自适应点成为自适应路径这种方式没有文章介绍. 下面的代码中给出了如何在自适应族文件中创建参照点并转换为自适应点连接…...
浏览器模块化难题
CommonJS 的工作原理 当使用 require(模块路径) 导入一个模块时,node会做以下两件事情(不考虑模块缓存): 通过模块路径找到本机文件,并读取文件内容将文件中的代码放入到一个函数环境中执行,并将执行后 m…...
详细介绍:网站背景更换功能
目录 1. HTML 部分 2. JavaScript 部分 3. 完整流程 4. 总结 5. 适用场景 本文将介绍如何通过文件上传实现网站背景图片的更换。通过使用 JavaScript 和 Axios,我们可以允许用户上传图片文件并将其作为网站的背景图片。上传的图片 URL 会保存在浏览器的 localSt…...
w190工作流程管理系统设计与实现
🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…...
Linux——文件系统
一、从硬件出发 1)磁盘的主要构成 通常硬盘是由盘片、主轴、磁头、摇摆臂、马达、永磁铁等部件组成,其中一个硬盘中有多块盘片和多个磁头,堆叠在一起,工作时由盘片旋转和摇摆臂摇摆及逆行寻址从而运作,磁头可以对盘片…...
傅里叶分析之掐死教程
https://zhuanlan.zhihu.com/p/19763358 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析 不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维模式。但不幸的是,傅里叶分析的公式看起来太复杂了,所以很多…...
使用scikit-learn中的K均值包进行聚类分析
聚类是无监督学习中的一种重要技术,用于在没有标签信息的情况下对数据进行分析和组织。K均值算法是聚类中最常用的方法之一,其目标是将数据点划分为K个簇,使得每个簇内的数据点更加相似,而不同簇之间的数据点差异较大。 准备自定…...
Compose笔记(一)--LifecycleEventObserver
这一节了解一下LifecycleEventObserver,它在 Android Compose 中是一个接口,它允许你监听 Android 组件(如 Activity、Fragment)的生命周期事件。Lifecycle 代表 Android 组件从创建到销毁的整个生命周期,而 Lifecycle…...
算法总结-二分查找
文章目录 1.搜索插入位置1.答案2.思路 2.搜索二维矩阵1.答案2.思路 3.寻找峰值1.答案2.思路 4.搜索旋转排序数组1.答案2.思路 5.在排序数组中查找元素的第一个和最后一个位置1.答案2.思路 6.寻找旋转排序数组中的最小值1.答案2.思路 1.搜索插入位置 1.答案 package com.sunxi…...
MySQL(InnoDB统计信息)
后面也会持续更新,学到新东西会在其中补充。 建议按顺序食用,欢迎批评或者交流! 缺什么东西欢迎评论!我都会及时修改的! 大部分截图和文章采用该书,谢谢这位大佬的文章,在这里真的很感谢让迷茫的…...
Spring Cloud工程搭建
目录 工程搭建 搭建父子工程 创建父工程 Spring Cloud版本 创建子项目-订单服务 声明项⽬依赖 和 项⽬构建插件 创建子项目-商品服务 声明项⽬依赖 和 项⽬构建插件 工程搭建 因为拆分成了微服务,所以要拆分出多个项目,但是IDEA只能一个窗口有一…...
MySQL锁类型(详解)
锁的分类图,如下: 锁操作类型划分 读锁 : 也称为共享锁 、英文用S表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。 写锁 : 也称为排他锁 、英文用X表示。当前写操作没有完成前,它会…...
Kafka SASL/SCRAM介绍
文章目录 Kafka SASL/SCRAM介绍1. SASL/SCRAM 认证机制2. SASL/SCRAM 认证工作原理2.1 SCRAM 认证原理2.1.1 密码存储和加盐2.1.2 SCRAM 认证流程 2.2 SCRAM 认证的关键算法2.3 SCRAM 密码存储2.4 SCRAM 密码管理 3. 配置和使用 Kafka SASL/SCRAM3.1 Kafka 服务器端配置3.2 创建…...
使用VCS进行单步调试的步骤
使用VCS对SystemVerilog进行单步调试的步骤如下: 1. 编译设计 使用-debug_all或-debug_pp选项编译设计,生成调试信息。 我的4个文件: 1.led.v module led(input clk,input rst_n,output reg led );reg [7:0] cnt;always (posedge clk) beg…...
计算机网络 应用层 笔记1(C/S模型,P2P模型,FTP协议)
应用层概述: 功能: 常见协议 应用层与其他层的关系 网络应用模型 C/S模型: 优点 缺点 P2P模型: 优点 缺点 DNS系统: 基本功能 系统架构 域名空间: DNS 服务器 根服务器: 顶级域…...
Node.js下载安装及环境配置
目录 一、下载 1. 查看电脑版本,下载对应的安装包 2. 下载路径下载 | Node.js 中文网 二、安装步骤 1. 双击安装包 2. 点击Next下一步 3. 选择安装路径 4. 这里我选择默认配置,继续Next下一步(大家按需选择) 5. 最后inst…...
LeetCode题练习与总结:任务调度器--621
一、题目描述 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表,用字母 A 到 Z 表示,以及一个冷却时间 n。每个周期或时间间隔允许完成一项任务。任务可以按任何顺序完成,但有一个限制:两个 相同种类 的任务之间必须有长…...
动手学深度学习-3.2 线性回归的从0开始
以下是代码的逐段解析及其实际作用: 1. 环境设置与库导入 %matplotlib inline import random import torch from d2l import torch as d2l作用: %matplotlib inline:在 Jupyter Notebook 中内嵌显示 matplotlib 图形。random:生成…...
鸿蒙HarmonyOS Next 视频边播放边缓存- OhosVideoCache
OhosVideoCache 是一个专为OpenHarmony开发(HarmonyOS也可以用)的音视频缓存库,旨在帮助开发者轻松实现音视频的边播放边缓存功能。以下是关于 OhosVideoCache 的详细介绍: 1. 核心功能 边播放边缓存:将音视频URL传递给 OhosVideoCache 处理后…...
#systemverilog# Verilog与SystemVerilog发展历程及关系
1. Verilog的发展历史 1984年:Gateway Design Automation公司开发了Verilog,最初作为专有语言,用于逻辑仿真和数字电路设计。 1990年:Cadence收购Gateway,Verilog逐步开放,成为行业标准。 1995年(IEEE 1364-1995):首个IEEE标准,即Verilog-1995,定义基础语法和仿真语…...
【集成Element Plus】
集成Element Plus 安装main.ts中全局引入安装图标库 安装 pnpm add element-plusmain.ts中全局引入 import ElementPlus from element-plus; import element-plus/dist/index.css;app.use(ElementPlus);安装图标库 pnpm install element-plus/icons-vue...
基于微信小程序的电子商城购物系统设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
进阶数据结构——双向循环链表
目录 前言一、定义与结构二、特点与优势三、基本操作四、应用场景五、实现复杂度六、动态图解七、代码模版(c)八、经典例题九、总结结语 前言 这一期我们学习双向循环链表。双向循环链表不同于单链表,双向循环链表是一种特殊的数据结构&…...
Kafka分区策略实现
引言 Kafka 的分区策略决定了生产者发送的消息会被分配到哪个分区中,合理的分区策略有助于实现负载均衡、提高消息处理效率以及满足特定的业务需求。 轮询策略(默认) 轮询策略是 Kafka 默认的分区策略(当消息没有指定键时&…...
【hot100】560和为K的子数组
一、思路 初步思路就是采用双循环以每个节点为头节点,然后向后遍历是否有满足和为K的子数组。 然后我们可以采用另一个新的思路,就是可以采用“前缀和的思路”,具体就是如果hashmap中存在sum-k的值,那就可以说明存在一个何为k的…...
【01】共识机制
BTF共识 拜占庭将军问题 拜占庭将军问题是一个共识问题 起源 Leslie Lamport在论文《The Byzantine Generals Problem》提出拜占庭将军问题。 核心描述 军中可能有叛徒,却要保证进攻一致,由此引申到计算领域,发展成了一种容错理论。随着…...
树莓派pico入坑笔记,故障解决:请求 USB 设备描述符失败,故障码(43)
今天心血来潮,拿出吃灰的pico把玩一下,打开thonny,上电,然后...... 上电识别不到端口,windows报错,请求 USB 设备描述符失败,故障码(43) 一开始以为是坏了(磕…...
大语言模型的个性化综述 ——《Personalization of Large Language Models: A Survey》
摘要: 本文深入解读了论文“Personalization of Large Language Models: A Survey”,对大语言模型(LLMs)的个性化领域进行了全面剖析。通过详细阐述个性化的基础概念、分类体系、技术方法、评估指标以及应用实践,揭示了…...
线程互斥同步
前言: 简单回顾一下上文所学,上文我们最重要核心的工作就是介绍了我们线程自己的LWP和tid究竟是个什么,总结一句话,就是tid是用户视角下所认为的概念,因为在Linux系统中,从来没有线程这一说法,…...
高效接口限流:基于自定义注解与RateLimiter的实践
在高并发场景下,接口的流量控制是保证系统稳定性和提升性能的关键之一。通过实现接口限流,我们可以有效避免系统在访问高峰时发生崩溃。本文将详细介绍如何通过自定义注解和切面编程结合RateLimiter来实现接口的限流功能,以应对高并发请求。 …...
嵌入式硬件篇---HAL库内外部时钟主频锁相环分频器
文章目录 前言第一部分:STM32-HAL库HAL库编程优势1.抽象层2.易于上手3.代码可读性4.跨平台性5.维护和升级6.中间件支持 劣势1.性能2.灵活性3.代码大小4.复杂性 直接寄存器操作编程优势1.性能2.灵活性3.代码大小4.学习深度 劣势1.复杂性2.可读性3.可维护性4.跨平台性…...
万字长文深入浅出负载均衡器
前言 本篇博客主要分享Load Balancing(负载均衡),将从以下方面循序渐进地全面展开阐述: 介绍什么是负载均衡介绍常见的负载均衡算法 负载均衡简介 初识负载均衡 负载均衡是系统设计中的一个关键组成部分,它有助于…...
使用递归解决编程题
题目:递归实现组合型枚举 从 1−n 这 n 个整数中随机选取 m 个,每种方案里的数从小到大排列,按字典序输出所有可能的选择方案。 输入 输入两个整数 n,m。(1≤m≤n≤10) 输出 每行一组方案,每组方案中…...
Nginx 中文文档
文章来源:nginx 文档 -- nginx中文文档|nginx中文教程 nginx 文档 介绍 安装 nginx从源构建 nginx新手指南管理员指南控制 nginx连接处理方法设置哈希调试日志记录到 syslog配置文件测量单位命令行参数适用于 Windows 的 nginx支持 QUIC 和 HTTP/3 nginx 如何处理…...
2.策略模式(Strategy)
定义 定义一系列算法,把它们一个个封装起来,并且使他们可互相替换(变化)。该模式使算法可独立于使用它的客户程序(稳定)而变化(拓展,子类化)。 动机(Motiva…...
浔川AI翻译v6.0延迟上线说明
浔川社团官方联合会关于浔川AI翻译v6.0版本的说明 尊敬的各位用户: 大家好! 首先,衷心感谢大家一直以来对浔川社团官方联合会以及浔川AI翻译的关注与支持。在此,我们怀着十分遗憾的心情向大家发布一则重要通知:原计划推…...
git基础使用--4---git分支和使用
文章目录 git基础使用--4---git分支和使用1. 按顺序看2. 什么是分支3. 分支的基本操作4. 分支的基本操作4.1 查看分支4.2 创建分支4.3 切换分支4.4 合并冲突 git基础使用–4—git分支和使用 1. 按顺序看 -git基础使用–1–版本控制的基本概念 -git基础使用–2–gti的基本概念…...
[paddle] 矩阵相关的指标
行列式 det 行列式定义参考 d e t ( A ) ∑ i 1 , i 2 , ⋯ , i n ( − 1 ) σ ( i 1 , ⋯ , i n ) a 1 , i 1 a 2 , i 2 , ⋯ , a n , i n det(A) \sum_{i_1,i_2,\cdots,i_n } (-1)^{\sigma(i_1,\cdots,i_n)} a_{1,i_1}a_{2,i_2},\cdots, a_{n,i_n} det(A)i1,i2,⋯,in…...