ThreadPool 模式设计与流程演示

一、背景技术

系统线程是一种稀缺资源且创建一个线程开销较大,频繁地创建和销毁线程反而可能使得系统在高并发时性能急剧下降。如果无限制地创建线程,不仅会消耗系统资源,还会降低系统的稳定性,甚至造成系统崩溃。

线程池的使用能够有效提升线程的可管理性,依据系统承受能力,调整线程池中工作线程的数量,对线程进行统一的分配、调优和监控。该方式能够提高任务响应速度,当任务到达时,无需等待线程创建即可立即执行。

由于时序数据采集涉及众多设备检测点且采集数据频繁,这将导致数据库中执行任务量多、并发程度高,如何在有限系统资源下维持系统稳定则尤为重要。

就上述问题及诉求,本期我们将和大家分享 ThreadPool 模块设计。该模式能够提高系统资源的使用效率,通过重复利用已创建线程避免频繁创建和销毁线程对系统资源的消耗,可保持系统执行大量高并发任务时的性能稳定,通过 ThreadPool 模式可实现统一资源管理,简化编程接口。

二、ThreadPool 整体设计

ThreadPool 在初始化阶段创建指定数量的线程并依次放在 all_thread 中(动态数组 vector,大小为传递至它的参数,不传递参数则默认大小为 128), 将指定数量且经过初始化的 thread_id 放入到 wait_threads (list)中。其他模块需要线程资源时,可通过 ThreadPool 接口请求获得线程资源,支持并发请求。

当 wait_threads 不为空时,为请求方提供一个 Thread 用于各项操作并返回 thread_id;当 wait_threads 中为空且线程池中线程数量没有达到上限时,尝试再次初始化部分 Thread,并将 thread_id 放入到 wait_threads (list)中以供上层调用。ThreadPool 模块负责处理 Thread 在创建与回收过程中的异常。

在这里插入图片描述
图 1 ThreadPool 整体设计

通过图 1 可知,在初始化过程中完成 ThreadPool 的创建与初始化。ThreadPool 在创建过程中会产生固定数量的 Thread 放入到 all_threads 数组中。ThreadPool 在初始化时需要指定最大线程数,并在 all_threads 中按照下标依次进行 Thread 的初始化。

当用户通过 ThreadPool 接口申请线程资源时,ThreadPool 模块会先检查 wait_threads 是否为空,若不为空则尝试获取一个 Thread 供给调用者使用,并返回 thread_id 给用户,同时将该 thread_id 放入到 busy_threads 中。

用户可以使用 ThreadPool 模块提供的接口同步等待操作执行结束,或者提前终止操作。用户释放 Thread 资源后,再将对应 thread_id 从 busy_threads 中取出放回到 wait_threads 中,等待后续调用。

在安全结束时,调用 ThreadPool 模块提供的接口进行关闭。首先,对 ThreadPool 状态进行标记,然后在 all_threads 循环调用 Thread 的退出方法,安全关闭 ThreadPool。

三、Thread 申请流程

在这里插入图片描述
图 2 Thread 申请流程用户使用

ThreadPool 接口申请 Thread 资源时,首先会检查 ThreadPool 是否已经关闭,如果已经关闭,则停止本次资源申请。如果 ThreadPool 状态正常,检查 wait_threads 中是否为空,即 ThreadPool 是否存在可用的线程。若存在就尝试获取一个 Thread,将对应 thread_id 返回给申请者;若不存在,检查当前 ThreadPool 线程数量是否超过了设定的最大值,若超过,则返回申请失败。若没有超过,则尝试继续初始化部分 Thread,将对应的 thread_id 放入到 wait_threads 中,以供用户进行申请及使用。

四、状态转移

在这里插入图片描述
图 3 Thread 状态转移过程

1. Thread 状态转移

ThreadPool 中的 Thread 在其整个生命周期中的状态有五种,如图 3 所示。在 ThreadPool 初始化阶段,Thread 状态均处于 INIT。ThreadPool 进行初始化,当 Thread 创建成功,状态转移至 WAIT ,否则转移至 ERROR,在 WAIT 状态下 Thread 资源空闲,可以对外提供服务。

用户调用 ThreadPool 的 applyThread(),成功获取到 Thread 后,对应的线程资源被锁定,Thread 状态转移至 RUNNING。用户可以通过 thread_id 调用 cancelThread() 向循环执行的任务发起取消指令,Thread 中循环执行的任务会通过 checkThreadStatus() 检查到取消指令后,将Thread 置为 CANCELLING,等待正在执行的任务终止并释放对应资源(或者是调用 Thread 的 joinThread()方法,等待线程结束操作并释放资源),等待任务结束后,Thread 状态转移至 WAIT。

不管 Thread 处于 WAIT 还是 RUNNING,用户调用 ThreadPool 的 stopThread() 后,正在执行循环任务的 Thread 状态都将从 RUNNING 转移至 CANCELLING,最终转移到 WAIT 后并销毁对应资源。其中 INIT、CANCELLING 状态为过渡状态。

2. ThreadPool 状态转移

ThreadPool 在其生命周期内的状态转移过程如图 4 所示,ThreadPool 对象创建完成后,其状态设定为 INIT,此时 ThreadPool 尚无法对外提供服务。在对 ThreadPool 执行完毕 InitThreadPool() 方法后(ThreadPool 对象只能被初始化一次)状态先转移成 INITIALIZAING;ThreadPool 中完成了 Thread 对象的创建,具备了对外提供服务的条件,此时状态转移成 RUNNING。

在这里插入图片描述

图 4 ThreadPool 状态转移过程

在对外提供服务过程中,随着越来越多的线程资源被占用,空闲的线程越来越少,当 ThreadPool 对象的 wait_threads 为空的时候,说明 ThreadPool 中暂时没有可用的 Thread。

如果此时外部申请 Thread 资源,ThreadPool 就需要继续创建 Thread 或者等待已创建的 Thread 回收,那么这个过程中 ThreadPool 会短暂地处于 BUSY 状态。

不管 ThreadPool 对象状态处于 RUNNING 还是 BUSY,当该对象的 StopThreadPool() 方法被调用时,ThreadPool 对象则需安全退出,ThreadPool 对象状态先转移至 STOPPING,等到 ThreadPool 对象停止对外提供服务,Thread 正在执行中的操作等待同步完成,ThreadPool 对象状态先转移至 STOPPED。其中, INITIALIZAING、STOPPING 状态为过渡状态。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(二十一)Flask之上下文管理第二篇(细细扣一遍源码)

每篇前言: 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 🔥🔥本文已收录于Flask框架从入门到实战专栏:《Flask框架从入…

postgresql慢查询排查和复现

postgresql慢查询排查和复现 一. 介绍一张表:pg_stat_activity pg_stat_activity 是 PostgreSQL 中一个非常有用的系统视图,提供了有关当前数据库连接和活动查询的信息。通过查询这个视图,你可以获取有关正在执行的查询、连接的用户、进程 …

Demo: 前端生成条形码并打印

前端生成条形码并打印 安装依赖&#xff1a; npm i print-js // 打印 npm i jsbarcode // 生成条形码 <template><div id"printContent" style"display: none;"><div id"elTable"><div class"name">名称&…

微信开放平台第三方授权(第二篇)

1.授权步骤开发 参考牛人的文档&#xff0c;按照步骤集成。 配置微信第三方平台中的授权事件接收URL&#xff1a;http://my-domain/notify/receive_ticket配置微信第三方平台中的公众号消息与事件接收URL http://my-domain/notify/APPID/callback首次启动后需要 等待收到 微信推…

VUE3动漫影视视频网站模板源码

文章目录 1.视频设计来源1.1 主界面1.2 动漫、电视剧、电影视频界面1.3 播放视频界面1.4 娱乐前线新闻界面1.5 关于我们界面 2.效果和源码2.1 动态效果2.2 源码结构 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/deta…

GBASE南大通用分享-ConnectionTimeout 属性

GBASE南大通用分享 获取或设置连接超时时间&#xff0c;值为‚0‛时没有限制。  语法 [Visual Basic] Public Overrides ReadOnly Property ConnectionTimeout As Integer Get [C#] public override int ConnectionTimeout { get; }  实现 IDbConnection.Connecti…

【文本到上下文 #7】探索 NLP 中的 Seq2Seq、编码器-解码器和注意力机制

一、说明 今天&#xff0c;我们将探讨序列到序列 &#xff08;seq2seq&#xff09; 模型的复杂工作原理&#xff0c;特别关注编码器-解码器架构和注意力机制。这些概念是各种 NLP 应用的基础&#xff0c;从机器翻译到问答系统。 这是可以期待的&#xff1a; Seq2Seq模型中的编码…

Android Automotive:在路上释放 Android 操作系统的力量

Android Automotive&#xff1a;在路上释放 Android 操作系统的力量 Android 在汽车行业的历程车载信息娱乐系统 (IVI) 的演变汽车中的 Android&#xff1a;演变和进步Android 汽车操作系统的崛起Polestar 2&#xff1a;开创 Android 汽车体验Android 开源项目 (AOSP) 及其他项…

ATAC-seq发篇测序文章就结束了吗?看如何利用ATAC-seq数据为后续关键基因的转录调控研究提供重要依据

染色质可及性&#xff08;Chromatin Accessibility&#xff09;是染色质的一种特性&#xff0c;为转录因子结合靶基因提供了空间。转座酶可及染色质测序分析&#xff08;ATAC-seq&#xff09;是常见的研究染色质可及性的方法&#xff0c;ATAC-seq联合RNA-seq是一种新的研究思路…

【前端开发】CSS中的:hover伪类选择器 你真的搞懂怎么去使用它吗?

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

某大厂关于Linux系统相关面试题

一、Linux系统和Shell 1、写一个sed命令&#xff0c;修改/tmp/input.txt文件的内容&#xff0c;要求&#xff1a;(1) 删除所有空行&#xff1b;(2) 在非空行前面加一个"AAA"&#xff0c;在行尾加一个"BBB"&#xff0c;即将内容为11111的一行改为&#xff1…

【Linux】第三十八站:信号处理

文章目录 一、信号处理二、再谈进程地址空间三、内核如何实现信号的捕捉四、sigaction 一、信号处理 我们知道&#xff0c;信号保存以后&#xff0c;会在合适的时候进行处理这个信号。 那么信号是如何被处理的&#xff1f;什么时候进行处理呢&#xff1f; 当我们的进程从内核…