【线程池项目(二)】线程池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模式的具体实现过程🔚🔚🔚

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

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

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

相关文章

2024年漳州本地有正规等保测评机构吗?在哪里?

我们大家都知道&#xff0c;企业办理等保一定要找有资质的等保测评机构。因此不少漳州企业在问&#xff0c;2024年漳州本地有正规等保测评机构吗&#xff1f;在哪里&#xff1f;这里我们小编通过查找来为大家解答一下&#xff0c;仅供参考&#xff01; 目前福建漳州本地没有正规…

Android | ArcGIS入门

一、概述 ArcGIS是由Esri开发的地理信息系统&#xff08;GIS&#xff09;软件。它用于制图、空间分析和数据可视化。ArcGIS允许用户以各种格式创建、管理、分析和共享地理信息。它通常用于城市规划、环境管理和应急响应等领域。该软件包括一系列工具&#xff0c;用于创建地图、…

为什么前端开发变得越来越复杂了?这可能是我们的错

前端训练营&#xff1a;1v1私教&#xff0c;终身辅导计划&#xff0c;帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~ Hello&#xff0c;大家好&#xff0c;我是 Sunday。 最近有很多同学来问我&#xff1a;“Sunday 老师&#xff0c;前端学起…

React 模态框的设计(二)

自定义组件是每个前端开发者必备的技能。我们在使用现有框架时难免有一些超乎框架以处的特别的需求&#xff0c;比如关于弹窗&#xff0c;每个应用都会用到&#xff0c;但是有时我们使用的框架中提供的弹窗功能也是功能有限&#xff0c;无法满足我们的应用需求&#xff0c;今天…

《TCP/IP详解 卷一》第2章 Internet地址结构

目录 2.1 引言 2.2 表示IP地址 2.3 基本的IP地址结构 单播地址 全球单播地址&#xff1a; 组播地址 任播地址 2.4 CIDR和聚合 2.5 特殊用途地址 2.6 分配机构 2.7 单播地址分配 2.8 与IP地址相关的攻击 2.9 总结 2.1 引言 2.2 表示IP地址 IPv4地址&#xff1a;3…

nginx重新编译添加模块或去除不需要的模块

在使用nginx中&#xff0c;我们可能需要对已经安装的nginx进行添加或者删除模块 1、先查看nginx安装了哪一些模块 nginx -V2、来到nginx源码目录&#xff0c;根据如下规则&#xff0c;自行根据需求更改命令 如果要去掉nginx自带的模块&#xff0c;就是用–without做为前缀进…

SpringBoot项目实现文件上传,MINIO+OSS阿里云

MINIO 安装以及部署 官网&#xff1a;MinIO | Code and downloads to create high performance object storage 下载后是一个minio.exe的文件&#xff0c;可以先创一个文件夹来存放数据以及文件 在文件的目录下cmd进入控制台 minio.exe server data 启动成功后控制台会打印账…

[NCTF2019]True XML cookbook --不会编程的崽

题目的提示很明显了&#xff0c;就是xxe攻击&#xff0c;直接抓包。 <?xml version "1.0"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <user><username> &xxe; </username><passwor…

H桥逆变控制方式(单极性倍频)

单极性倍频图像 内部做了载波取反&#xff1a;正相载波和负相载波 最后都和调制载波一起比较 正相载波&#xff1a;Q7导通为高电平&#xff0c;Q15导通为低电平 负相载波&#xff1a;Q16导通为高电平&#xff0c;Q8导通为低电平 导通次序为&#xff1a;Q7Q16——Q7Q8——Q7Q…

OpenHarmony JS和TS三方组件使用指导

OpenHarmony JS和TS三方组件介绍 OpenHarmony JS和TS三方组件使用的是OpenHarmony静态共享包&#xff0c;即HAR(Harmony Archive)&#xff0c;可以包含js/ts代码、c库、资源和配置文件。通过HAR&#xff0c;可以实现多个模块或者多个工程共享ArkUI组件、资源等相关代码。HAR不…

【MATLAB】CEEMD_ MFE_SVM_LSTM 神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 CEEMD_MFE_SVM_LSTM神经网络时序预测算法是一种结合了多种先进技术的复杂预测方法&#xff0c;旨在提高时序预测的准确性和稳定性。下面是对该算法的详细介绍&#xff1a; CEEMD&#xff…

Linux进一步研究权限-----------ACL使用

一、使用情况 1.1、场景: 某个大公司&#xff0c;在一个部门&#xff0c;有一个经理和手下有两个员工&#xff0c;在操控一个Linux项目,项目又分为三期做&#xff0c;然而一期比较重要&#xff0c;经理带着员工做完了&#xff0c;公司就觉得技术难点已经做完攻克了&#xff0…

Redis可视化工具——RedisInsight

文章目录 1. 下载2. 安装3. RedisInsight 添加 Redis 数据库4. RedisInsight 使用 RedisInsight 是 Redis 官方出品的可视化管理工具&#xff0c;支持 String、Hash、Set、List、JSON 等多种数据类型的管理&#xff0c;同时集成了 RedisCli&#xff0c;可进行终端交互。 1. 下载…

npm login报错 ‘proxy‘ config is set properly. See: ‘npm help config‘

报错提示 解决办法 按照以下的顺序执行命令行 检查自己的代理 npm config get proxy npm config get npm config get https-proxy npm config get registry代理和缓存置空并且设置新镜像 npm config set proxy null npm config set https-proxy null npm config set regist…

vite+ts+vue3项目配置

如何生成用户代码片段&#xff08;快捷生成代码&#xff09; 点击用户代码片段 新建全局代码片段&#xff0c;然后起个名字 {"vue": {"prefix": "vue","body": ["<template>"," <div class\"contai…

如何使用逻辑回归处理多标签问题?

逻辑回归处理多分类 1、背景描述2、One vs One3、One VS Rest4、从Sigmoid到Softmax的推导 1、背景描述 逻辑回归本身只能用于二分类问题&#xff0c;如果实际情况是多分类的&#xff0c;那么就需要对模型进行一些改动。下面介绍三种常用的将逻辑回归用于多分类的方法 2、One …

200万上下文窗口创飞Gemini 1.5!微软来砸谷歌场子了

谷歌刚刷新大模型上下文窗口长度记录&#xff0c;发布支持100万token的Gemini 1.5&#xff0c;微软就来砸场子了。 推出大模型上下文窗口拉长新方法——LongRoPE&#xff0c;一口气将上下文拉至2048k token&#xff0c;也就是200多万&#xff01; 并且1000步微调内&#xff0c…

移动端自动化常用的元素定位工具 介绍

在移动端自动化测试和开发中&#xff0c;元素定位是非常关键的一步。以下是一些常用的工具和技术来帮助开发者或测试工程师在移动设备上定位元素&#xff1a; 1. **UiAutomator**: - **UiAutomator** 是 Android 官方提供的自动化测试框架。它可以用来编写测试脚本&…

vue3 vite 经纬度逆地址解析

在web端测试经纬度逆地址解析有2中方式&#xff0c;先准备好两个应用key 第一种&#xff0c;使用“浏览器端”应用类型 const address ref() const latitude ref() // 经度 const longitude ref() // 纬度 const ak 你的key // 浏览器端 function getAddressWeb() {// 创建…

单片机04__基本定时器__毫秒微秒延时

基本定时器__毫秒微秒延时 基本定时器介绍&#xff08;STM32F40x&#xff09; STM32F40X芯片一共包含14个定时器&#xff0c;这14个定时器分为3大类&#xff1a; 通用定时器 10个 TIM9-TIM1和TIM2-TIM5 具有基本定时器功能&#xff0c; 还具有输入捕获&#xff0c;输出比较功…