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

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

如果需要与本篇博客完全匹配的实现代码,也可以在 我的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模式的具体实现过程🔚🔚🔚

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习(17)--DataLoader自定义数据集制作

目录 DataLoader自定义数据集制作 1.从标注文件(txt文件)中读取数据和标签 2.分别把数据和标签存在两个list中 3.设置完整的图像数据路径 4.根据任务整合出一个数据处理类 5.数据预处理 6.使用定义好的类来实例化DataLoader 7.检查数据和标签是否对应 8.使用创建好的D…

【行业会议】优积科技应邀参加住建部模块建筑企业2023年工作座谈会

2023年3月2日&#xff0c;优积建筑科技发展&#xff08;上海&#xff09;有限公司&#xff08;以下简称“优积科技”&#xff09;应邀参加由住房和城乡建设部科技与产业化发展中心&#xff08;以下简称“住建部科技与产业化中心”&#xff09;组织召开的模块建筑企业2023年工作…

OpenCV 4基础篇| OpenCV图像基本操作

目录 1. 图像读取1.1 cv2.imread() 不能读取中文路径和中文名称1.2 cv2.imdecode() 可以读取中文路径和中文名称 2. 图像的显示2.1 openCV显示图像 cv2.imshow()2.2 matplotlib显示图像 plt.imshow() 3. 图像的保存 cv2.imwrite()4. 图像的复制4.1 img.copy()4.2 np.copy()4.3 …

基于java springboot的图书管理系统设计和实现

基于java springboot的图书管理系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源码联…

Ansible 简介及部署 基础模块学习 ansible部署rsync 及时监控远程同步

Ansible介绍&#xff1a; Ansible 是一个配置管理系统&#xff0c;当下最流行的批量自动化运维工具之一&#xff0c;它是一款开源的自动化工具&#xff0c;基于Python开发的配置管理和应用部署的工具。 Ansible 是基于模块工作的&#xff0c;它只是提供了一种运行框架&#xff…

【深度学习】Pytorch 系列教程(七):PyTorch数据结构:2、张量的数学运算(5):二维卷积及其数学原理

文章目录 一、前言二、实验环境三、PyTorch数据结构1、Tensor&#xff08;张量&#xff09;1. 维度&#xff08;Dimensions&#xff09;2. 数据类型&#xff08;Data Types&#xff09;3. GPU加速&#xff08;GPU Acceleration&#xff09; 2、张量的数学运算1. 向量运算2. 矩阵…

书生·浦语大模型实战营第四节课作业

基础作业 fintune过程 这里要注意下。 合并完参数的模型再进行网页部署时&#xff0c;需要用到InternLM源码&#xff0c;教程里面忽略了需要commit版本。通过以下命令转到所需版本&#xff0c;然后就可以看到web_demo.py。 cd InternLM git checkout 3028f07cb79e5b1d7342f4…

Servlet实现图片的上传和显示

本篇文章是在上一篇文章上改进而来 一、图片上传需要引用的jar包 链接&#xff1a;https://pan.baidu.com/s/17FLjlWlNEG5YnS_dl3C8WA 提取码&#xff1a;wbis 二、最后的结果 三、更改数据库增加图片路径字段path 四、前端页面增加图片上传按钮,和上传的复选框 代码 上传…

ChatGPT 4.0 升级指南

1.ChatGPT 是什么&#xff1f; ChatGPT 是由 OpenAI 开发的一种基于人工智能的聊天机器人&#xff0c;它基于强大的语言处理模型 GPT&#xff08;Generative Pre-trained Transformer&#xff09;构建。它能够理解人类语言&#xff0c;可以为我们解决实际的问题。 1.模型规模…

vue+node.js美食分享推荐管理系统 io551

&#xff0c;本系统采用了 MySQL数据库的架构&#xff0c;在开始这项工作前&#xff0c;首先要设计好要用到的数据库表。该系统的使用者有二类&#xff1a;管理员和用户&#xff0c;主要功能包括个人信息修改&#xff0c;用户、美食类型、美食信息、订单信息、美食分享、课程大…

Camunda7.18流程引擎启动出现Table ‘camunda_platform_docker.ACT_GE_PROPERTY‘的解决方案

文章目录 1、问题描述2、原因分析3、解决方案3.1、方案一&#xff1a;降低mysql版本3.2、方案二&#xff1a;增加nullCatalogMeansCurrent参数&#xff08;推荐&#xff09; 4、总结 1、问题描述 需要在docker中&#xff0c;部署Camunda流程引擎。通过启动脚本camunda-platfor…

【LeetCode-337】打家劫舍III(动态规划)

目录 题目描述 解法1&#xff1a;动态规划 代码实现 题目链接 题目描述 在上次打劫完一条街道之后和一圈房屋后&#xff0c;小偷又发现了一个新的可行窃的地区。这个地区只有一个入口&#xff0c;我们称之为“根”。 除了“根”之外&#xff0c;每栋房子有且只有一个“父“…

JVM内存随着服务器内存的升高而升高问题排查

一、故障描述 公司测试环境和线上环境&#xff0c;都会有&#xff1a;JVM内存随着服务器内存的升高而升高 这种问题 二、排查 1、linux服务器上使用htop查看java项目内存占比&#xff0c;给最大最小推内存300m&#xff0c;但是实际上超出一倍 2、排查方案 a、通过后面的学习…

Games 103 作业四

Games 103 作业四 第四次作业就是流体模拟了&#xff0c;作业中给了若干的实现步骤&#xff0c;以及一些模板代码。 首先第一步&#xff0c;在update函数的开头&#xff0c;加载水面mesh的高度&#xff0c;然后在update的结束时&#xff0c;把计算后的高度更新到mesh中。这个很…

CSDN原力值怎么提升?

文章目录 前言一、原力值怎么看二、提升原力值的方法1.原力值↑2.原力值↓提示!!!禁止在csdn网站内进行违规行为!!! 结束语 前言 在前面一篇文章中&#xff0c;我讲了付费收看的条件&#xff0c;有需要的先把网址收藏起来&#xff01; https://blog.csdn.net/m0_69481332/arti…

【坑】Spring Boot整合MyBatis,一级缓存失效

一、Spring Boot整合MyBatis&#xff0c;一级缓存失效 1.1、概述 MyBatis一级缓存的作用域是同一个SqlSession&#xff0c;在同一个SqlSession中执行两次相同的查询&#xff0c;第一次执行完毕后&#xff0c;Mybatis会将查询到的数据缓存起来&#xff08;缓存到内存中&#xf…

【Java面试系列】Nginx

目录 为什么要用Nginx&#xff1f;为什么Nginx性能这么高&#xff1f;Nginx 是如何实现高并发的&#xff1f; Nginx怎么处理请求的&#xff1f;Nginx的工作流程 给 favicon.ico 和 robots.txt 设置过期时间; 这里为 favicon.ico 为 99 天,robots.txt 为 7 天并不记录 404 错误日…

前沿科技速递——YOLOv9

随着YOLO系列的不断迭代更新&#xff0c;前几天&#xff0c;YOLO系列也迎来了第九个大型号的更新&#xff01;YOLOv9正式推出了&#xff01;附上原论文链接。 arxiv.org/pdf/2402.13616.pdf 同样是使用MS COCO数据集进行对比比较&#xff0c;通过折线图可看出AP曲线在全方面都…

2024比较赚钱的项目是什么?亲身经历,月入过万!

我是电商珠珠 年后找项目这件事&#xff0c;成为了部分人所焦虑的一点&#xff0c;有的想要兼职&#xff0c;有的在考虑全职。至于做什么还没有一丝头绪。大家都知道短视频很火&#xff0c;于是有直播能力的人就吃上了流量红利&#xff0c;开始做达人带货&#xff0c;拍视频接…

Linux下“一切皆文件”

“Linux下一切皆文件” Linux 下一切皆文件这个说法是指 Linux 系统中的一种设计理念&#xff0c;即将所有设备、资源和进程等抽象为文件或文件夹的形式。这种设计理念的好处在于统一了对待不同类型资源的方式&#xff0c;提供了统一的接口和工具来进行管理和操作。 Linux 下…