【线程池项目(二)】线程池FIXED模式的实现

news2024/10/6 8:39:19

在上一篇【线程池项目(一)】项目介绍和代码展示 中,我们展示了线程池的两个版本实现,它们的代码在具体的实现细节上是优化过了的。下文提供的代码并非完整,也有很多地方尚需改善,但这些差异对理解整个项目而言,影响并不会太大。因此,在接下来的讨论中,我们将重点放在对项目代码的理解上。

如果需要与本篇博客完全匹配的实现代码,也可以在 我的gitee 上下载对应的源码

项目经历——基于C++新特性以及模板编程实现的线程池

    • 一、设计思路
    • 二、关键技术点
      • (1)线程池类ThreadPool
      • (2)线程类Thread
      • (3)信号量类Semaphore
      • (4)上帝类Any
      • (5)任务抽象基类Task
      • (6)提交任务的返回值Result
    • 三、分析图例,理解函数执行过程
    • 四、总结

一、设计思路

使用C++ OOP面向对象编程的思想,设计了6个类:

  • ThreadPool: 负责线程池的创建ThreadPool();、开启start()、设置模式setMode(这里不需要,默认FIXED)、提交任务submitTask()、线程函数threadFunc()(至于为什么要把线程函数放入ThreadPool里,而不是在Thread里,后面会解释)
  • Thread: 负责线程的创建Thread(),定义了函数对象类型ThreadFunc
  • Task: 对外(即用户)提供一个抽象类接口,用户可以重写run()函数来提供相应任务
  • Any: 模仿C++17中的any,可以接收任意的类型
  • Result: 作为Any的依赖,接收task任务在用户提交完成后的返回值类型
  • Semaphore: 线程的通信机制,模仿C++20的Semaphore,用于通知用户提交的任务是否已经被相应的线程执行完毕

二、关键技术点

(1)线程池类ThreadPool

🤠开启线程池start():
当创建线程对象时,我们使用 std::bind()绑定器将线程池的成员方法 threadFunc与当前线程池的 this 指针绑定到一起,作为创建线程对象的一个参数,传递给 std::thread 线程对象。这样,在 Thread 类的成员方法中,就可以直接通过调用 ThreadPool 的线程函数 threadFunc 来访问线程池中的成员变量和方法。通过这种绑定方式,也可以解决变参的问题,因为所有相关的参数都已经被绑定到这个线程函数上。因此,我们可以使用别名 using ThreadFunc = std::function<void()> 来定义线程函数的类型。
在这里插入图片描述


🥳提交任务submitTask():
使用互斥锁unique_lock()来维护线程安全,结合条件变量notFull的使用,判断1s内,任务队列中任务的数目是否已达上限,若已达,则阻塞返回提交失败,反之入队,通知其余线程任务队列中有任务能够执行了,返回提交成功任务的返回值Result(sp, true(default)),关于Result见下文
在这里插入图片描述


🥸线程函数threadFunc():
由于线程函数需要获取任务队列里的任务,在获取任务的同时需要线程池中互斥锁和条件变量的管理,直接定义在Thread里不好进行相关操作,定义在全局中也不好访问私有的成员变量,所以把它放在ThreadPool里实现,但是我们的目的是让线程通过线程函数来执行任务,所以我们定义相应的Thread构造函数把ThreadPool的线程函数threadFunc给到Thread,用Thread类的成员变量func_来存储。代码同上,就不赘述了
在这里插入图片描述

(2)线程类Thread

😎 这里没什么可说的,就是一个分离线程detach,延长线程函数的生命周期至主线程结束(即创建线程池的线程)
在这里插入图片描述

(3)信号量类Semaphore

🤓 模拟C++20的semaphore,用waitpost分别申请和释放信号量资源来控制用户提交的任务是否被执行完毕
在这里插入图片描述

(4)上帝类Any

🧐 考虑到用户提交任务时,可能不仅仅需要把任务处理完成,还可能需要得到任务处理完成后的返回值,所以我们设计了一个Any类作为接收任意类型的返回值,即让一个类型可以指向其他的任意类型。然我们知道,基类指针可以执行派生类对象,根据data(存储用户返回的数据,用模板实现)构造出一个派生类对象,这时候我们就可以使用Any里的基类指针指向它,并通过向下转型取出data。这里需要理解一下Any的构造函数,编译器在用户提交的任务执行完返回时是如何处理的
在这里插入图片描述

(5)任务抽象基类Task

😯 由于TaskResult是有耦合的,Result里用智能指针shared_ptr定义的Task类型的成员变量task_,为了避免发生智能指针的交叉引用问题,Task里使用了裸指针定义Result类型的result_,指向用户提交任务后返回的Result,其生命周期 > task, 通过result_Task里面调用Result里的成员方法,来控制Any返回值的获取,在exec()中发生多态调用(run()在基类中为纯虚函数,供用户重写)
在这里插入图片描述

(6)提交任务的返回值Result

😳 构造函数Result(…):
判断提交任务是否成功,并把当前对象this给到成员变量task_里,供Task类中的相关方法使用,如上
在这里插入图片描述


🥹 获取返回值Any ,setVal()、get():
通过信号量的waitpost操作和资源转移std::move()来进行
在这里插入图片描述

三、分析图例,理解函数执行过程

在这里插入图片描述

四、总结

以上就是有关于【线程池项目(二)】线程池FIXED模式的实现的内容,下一篇【线程池项目(三)】介绍线程池fixed模式的具体实现过程🔚🔚🔚

🌻🌻🌻如果聪明的你浏览到这篇文章并觉得文章内容对你有帮助,请不吝动动手指,给博主一个小小的赞和收藏🌻🌻🌻

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

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

相关文章

IT廉连看——C语言——分支语句

IT廉连看—分支语句 一、什么是语句 C语句可分为以下五类&#xff1a; 表达式语句 函数调用语句 控制语句 复合语句 空语句 本周后面介绍的是控制语句。 控制语句用于控制程序的执行流程&#xff0c;以实现程序的各种结构方式&#xff0c;它们由特定的语句定义符组成&…

字符串(算法竞赛)--字典树Trie与最大异或对

1、B站视频链接&#xff1a;F06 字典树(Trie)_哔哩哔哩_bilibili 题目链接&#xff1a;【模板】字典树 - 洛谷 #include <bits/stdc.h> using namespace std; const int N100010; int n; char s[N]; int ch[N][26];//ch[0][2]1表示0号节点通过c边走到了节点1 int cnt[…

2024最新前端面试题

数组是属于Object类型的&#xff0c;也就是引用类型&#xff0c;所以不能使用 typeof 来判断其具体类型。下面这些方法是判断数组的几种方法&#xff1a; 1、instanceof运算符 主要是判断某个实例&#xff08;arr&#xff09;是否属于某个对象。 let arr [1,2,3]; console.l…

eclipse中open Type 、 open type in Hierachy、open Resource的区别

目录 场景&#xff1a; open Type open Resource open type in Hierachy 场景&#xff1a; 在项目中想要研究底层代码&#xff0c;经常要用eclipse看依赖jar包的类&#xff0c;比如spring的源码中AbstractApplicationContext类CTLSHIFTT用的少&#xff0c;经常用的CTLSHIR…

给大家分享一款小程序:AI一秒修图

AI一秒修图 照片修复的AI助手特点&#xff1a;Demo&#xff08;1.选择图片 2.涂抹遮罩 3.消除&#xff09;Product Roadmap (版本演进)Contact-联系我们Reference 照片修复的AI助手 照片修复小小助手是一款快速P图微信小程序&#xff0c;用来消除图片中指定的人和物&#xff…

[算法沉淀记录] 排序算法 —— 冒泡排序

排序算法 —— 冒泡排序 基本概念 冒泡排序是一种简单的排序算法。它重复地遍历要排序的列表&#xff0c;一次比较两个元素&#xff0c;并交换它们的位置&#xff0c;如果它们不是按照升序排列的。这步遍历是重复进行的&#xff0c;直到没有再需要交换&#xff0c;也就是说该…

【设计模式】策略模式及函数式编程的替代

本文介绍策略模式以及使用函数式编程替代简单的策略模式。 策略模式 在策略模式&#xff08;Strategy Pattern&#xff09;中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。 在策略模式定义了一系列算法或策略&#xff0c;并将每个算法封装在独立…

介绍 PIL+IPython.display+mtcnn for 音视频读取、标注

1. nn.NLLLoss是如何计算误差的? nn.NLLLoss是负对数似然损失函数&#xff0c;用于多分类问题中。它的计算方式如下&#xff1a;首先&#xff0c;对于每个样本&#xff0c;我们需要将其预测结果通过softmax函数转换为概率分布。softmax函数可以将一个向量映射为一个概率分布&…

Three.js加载PLY文件

这是官方的例子 three.js webgl - PLY 我在Vue3中使用&#xff0c;测试了好久始终不显示点云数据。在网上查询后发现ply文件要放置在public目录下才行 <el-row><el-button type"primary" class"el-btn" click"IniThree1">PLY</…

【C++初阶】--类和对象(下)

目录 一.const成员 1.权限放大问题 2.权限的缩小 二.再谈构造函数 1.构造函数体赋值 2.初始化列表 (1)概念 (2)使用 ①在对象实例化过程中&#xff0c;成员变量先依次进行初始化 ②再进行函数体内二次赋值 3.explicit关键字 (1)C为什么要存在自动隐式类型转换…

Java之线程同步、synchronized用法及原理

线程的同步 场景1&#xff1a;两个线程同时访问一个变量&#xff0c;一个线程自增&#xff0c;一个线程自减 public class thread11 {public static void main(String[] args) throws InterruptedException {Thread thread1 new AddThread();Thread thread2 new DecThread(…

编曲学习:高叠和弦 挂留和弦 和弦实战应用

高叠和弦 挂留和弦 和弦实战应用小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_65d4826fe4b04c10a1310517?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 七和弦 以三和弦举例,三和弦上面叠一个三度的音,就变成了七和弦。 从下到…

opencv python投影变换效果

变换原理&#xff1a; https://www.cnblogs.com/txwtech/p/18024547 python示范代码&#xff1a; src2原图&#xff0c;4个坐标点 dst2转换后&#xff0c;4个坐标点 p_touyin cv2.getPerspectiveTransform(src2,dst2) #计算投影变换矩阵 #利用矩阵值进行图像投影变换 r…

全流程点云机器学习(二)使用PaddlePaddle进行PointNet的机器学习训练和评估

前言 这不是高支模项目需要嘛&#xff0c;他们用传统算法切那个横杆竖杆流程复杂耗时很长&#xff0c;所以想能不能用机器学习完成这些工作&#xff0c;所以我就来整这个工作了。 基于上文的数据集切分 &#xff0c;现在来对切分好的数据来进行正式的训练。 本系列文章所用的…

【Pytorch深度学习开发实践学习】B站刘二大人课程笔记整理lecture11 Advanced_CNN 实现GoogleNet和ResNet

【Pytorch深度学习开发实践学习】B站刘二大人课程笔记整理lecture11 Advanced_CNN 代码&#xff1a; Pytorch实现GoogleNet import torch from torchvision import datasets, transforms from torch.utils.data import DataLoader import torch.nn as nn import torch.nn.fun…

内核解读之内存管理(8)什么是page cache

文章目录 0. 文件系统的层次结构1.什么是page cache2.感观认识page cache3. Page Cache的优缺点3.1 Page Cache 的优势3.2 Page Cache 的劣势 0. 文件系统的层次结构 在了解page cache之前&#xff0c;我们先看下文件系统的层次结构。 1 VFS 层 VFS &#xff08; Virtual Fi…

【Ubuntu】解决Ubuntu 22.04开机显示器颜色(高对比度/反色)异常的问题

使用Ubuntu 22.04时强制关机了一下&#xff08;make -j16把电脑搞崩了&#xff09;&#xff0c;开机后系统显示的颜色异常&#xff0c;类似高对比度或反色&#xff0c;如下图。看着很难受&#xff0c;字体也没办法辨认。还好之前遇到过类似的问题&#xff0c;应该是一个配置文件…

装修避坑干货|阳台洗衣柜洗衣机一体柜设计。福州中宅装饰,福州装修

装修的时候常常会在洗衣柜中嵌入洗衣机&#xff0c;其实阳台柜的安装并不像看起来的那么简单&#xff0c;下面给大家说说几个注意事项‼️ 01.水电位置 在安装阳台柜之前&#xff0c;务必确认水电管道的位置。确保阳台柜不会阻碍水电管道的使用&#xff0c;以免造成不必要的麻…

Three.js-02Vue框架入手

1.创建项目 说明&#xff1a;默认有vue基础&#xff0c;node版本18以上。 vue create threejs 2.选择vue3 4.安装 npm i three 5. 修改页面 <template> <div></div> </template><script setup> import * as THREE from three;const width win…

查看仓库版本记录

打开命令行窗口 输入git log即可。 若发现分支不对&#xff0c;方法如下 查看项目目录&#xff0c;命令行输入dir可以查看 多个moudel&#xff0c;进入到需要查版本记录的moudel下 命令行输入cd .\文件名如wowo-win-server\ 切换到wowo-win-server文件夹下后&#xff0c;再输入…