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 状态为过渡状态。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
.NET8动态PGO简析
原文:.NET8动态PGO简析 作者:江湖评谈,公众号同名:江湖评谈(Jianghupt),欢迎关注。 前言 .NET8在性能方面的惊人飞跃,远超过去所取得成就,这在很大程度上归功于动态PGO。【 I dare say the improvements in .NET 8 in the JIT are an incredible leap beyond what was achieved in the past, in large part due to dynamic PGO…官方原话】 详细 在早期的.NET方法只编译一次,在第一次调用该方法的时候,JIT启动以生成该方法的代码。后续的调用以及当前的调用都会使用JIT生成的代码来运行程序,这是一个简单的无冲突的时代,但是也是一个原始的时代。 简单和原始在于,方法只编译一次,再无其它可能性。无冲突在于,尤其是.NET开源时代,分层,动态PGO,OSR等等都会破坏原有的代码逻辑,造成一定的复杂度,而早期的.NET不存在这种状况。 优化是编译器里面最耗时的操作,编译器可以花费超长的时间来优化一段代码或者一个指令集。但是程序使用者,或者软...
- 下一篇
GaussDB数据库中的同义词SYNONYM
目录 一、前言 二、GasussDB数据库中的Synonym 1、Synonym的概念 2、语法介绍 3、Synonym的用途 三、Synonym在GaussDB数据库中是如何使用的 1、表的同义词使用(示例) 2、视图的同义词使用(示例) 3、函数的同义词使用(示例) 4、存储过程的同义词使用(示例) 5、在GaussDB数据库中使用同义词时的注意事项 四、小结 一、前言 在GasussDB数据库中,Synonym是一种灵活且强大的工具,用于简化数据库对象的访问和管理。通过Synonym,用户可以创建具有特定名称的别名,以替代复杂的数据库对象名称,从而提高查询效率、方便维护、增强安全性,并扩展数据库的使用范围。 二、GasussDB数据库中的Synonym 1、Synonym的概念 同义词(Synonym)是数据库中的一个对象,它是一个别名,经常用于简化对象访问和提高对象访问的安全性。在GaussDB数据库中,管理员可以为大部分对象,如表、视图、序列、存储过程、包等等,定义同义词。 2、语法介绍 1)创建一个同义词对象。同义词是数据库对象的别名,用于记录与其他数据库对象名间的映射关系...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS关闭SELinux安全模块
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Hadoop3单机部署,实现最简伪集群
- CentOS6,7,8上安装Nginx,支持https2.0的开启