【C++ 面向对象编程】补档:线程池和 MySQL 连接池的设计模式分析

文章目录

推荐一个零声教育学习教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,点击立即学习: https://github.com/0voice 链接

前言

我之前写过一篇文章,是介绍 C++ 设计模式的,原文链接 在此。本篇文章小试牛刀,尝试分析之前写过的线程池和 MySQL 连接池的设计,各自的原文链接分别是 手撕 C++ 线程池手撕 MySQL 连接池

线程池的设计模式分析

还是给出那个思考步骤。

设计模式 = 使用场景 + 面向接口编程 + 稳定点 / 不稳点分析 设计模式 = 使用场景 + 面向接口编程 + 稳定点/不稳点分析 设计模式=使用场景+面向接口编程+稳定点/不稳点分析

应用场景:

1、线程池有若干个工作线程,这些工作线程是可以复用的。

2、当无任务推送过来的时候,线程处于休眠状态,不占用计算机资源。

3、当所有工作线程都在工作的时候,还需要把一路推送过来的任务储存起来。

应该解决的问题
稳定点 :即依赖关系。线程主动在其所在的线程池内寻找任务。线程主动执行任务。任务都是同一类型的。
不稳定点:一对多的对应关系。一个线程池有任意多个任务,同时也可以有任意多个线程。

我们发现有三个角色的三角关系要处理,线程池、线程、任务。接下来用面向接口编程的思维去思考。

解决稳定点 (里氏替换原则、单一职责原则、最小知道原则)

1、线程已有现成的架构,无需我们去多想,构造线程的时候,就已经同时运行其任务函数了。

2、线程池应该提供一个接口,这个接口就是工作线程的任务调度函数,让其按时机执行任务。

解决不稳定点 (接口隔离原则 (ISP)、开放封闭原则 (OCP)、依赖倒置原则 (DIP))

1、线程池体内组合线程成员接口,线程按照 vector 容器组织起来。线程执行的任务调度函数来自线程池。

2、线程池体内组合任务队列接口,组织任务的是 "拥塞队列",并且还要提供 post 任务的接口。

3、拥塞队列应该有,push、pop、cancel 三个接口,一个是推送、取出任务,销毁线程池。除此之外,还要准备同步原语,保证任务队列的线程安全。在原文,我是把它设计成双交换队列,提高其任务吞吐量。

结合起来说:

1、线程池与线程之间是观察者模型。线程池是一个被观察的对象,而线程是观察线程池的观察者,具体来说是观察线程池里的任务拥塞队列。

2、线程池与任务拥塞队列之间是代理关系,线程池的 post 接口代理了拥塞队列的 push 接口。

经过分析,归纳成如下图

首先是线程池


之后是拥塞队列


整体架构如下


MySQL 连接池的设计模式分析

还是给出那个思考步骤。

设计模式 = 使用场景 + 面向接口编程 + 稳定点 / 不稳点分析 设计模式 = 使用场景 + 面向接口编程 + 稳定点/不稳点分析 设计模式=使用场景+面向接口编程+稳定点/不稳点分析

应用场景:

1、MySQL 连接池有若干个 MySQL 的连接,对应多个工作线程处理该连接。

2、当无任务 SQL 语句要执行的时候,线程处于休眠状态,不占用计算机资源。.

3、当所有工作线程都在工作的时候,还需要把一路推送过来的任务 SQL 储存起来。

4、可对 SQL 查询的结果进行某种数据处理。

应该解决的问题
稳定点 :即依赖关系。线程主动在其所在的连接池池内寻找任务。线程主动执行任务 SQL。任务 SQL 都是同一类型的,查询的结果都是同一类型的。
不稳定点:一对多的对应关系。一个 MySQL 连接池有任意多个任务 SQL(当然也是有对应多个查询结果)、连接任意多个数据库数据表,同时也可以有任意多个线程与对应多个的 MySQL 连接。数据处理器可以处理任意多个数据任务。

我们发现有四个角色的四角关系要处理,连接池、线程/连接、任务 SQL、数据处理器。接下来用面向接口编程的思维去思考。

  • MySQL 连接池

    解决稳定点:

    ------1、提供连接池资源配置接口,

    ------2、提供外界输入 SQL 语句的接口(同时代理 sql 语句拥塞队列的 push 接口)

    解决不稳定点:(组合优于继承,开闭原则)

    ------1、使用 vector 容器包纳 mysql连接 和 对应线程(还需要提供任务调度函数接口)

    ------2、使用 sql 任务语句拥塞队列容器包纳 sql 查询任务(提供 pop、push 接口)

    ------3、使用 vector 容器包纳多个数据库的信息

    ------4、连接/线程 的调度函数接口会主动的操作拥塞队列,从中取出 sql 语句去执行

    ------5、使用 vector 容器包纳多个 mysql 查询结果接口

  • 优化组合1,连接池工作者 MySQLWorker

    ------1、把线程接口和 MySQL 连接接口组合起来,并且可以同时观察 SQL 语句拥塞队列(拥有其指针)

    ------2、提供 SQL 语句调度函数,是可以去拥塞队列里面 pop 出 sql 语句

  • 优化组合2,连接接口 MySQLConn

    ------1、组合接口 MySQLWorker 和连接配置信息 sql::Connection

    ------2、提供数据库查询接口 Query

  • MySQLWorker 补充组合

    ------1、MySQLWorker 补充接口 MySQLConn

  • 优化组合4,SQLOperation 查询操作

    ------1、把官方库的查询结果接口、sql 语句字符串组合起来

    ------2、提供 sql 语句的执行接口 Excute (worker 执行)和对外通信接口 GetFuture(处理器获取)

    ------3、把拥塞队列的内容变成 SQLOperation

  • 异步处理器

    解决稳定点:

    ------1、提供外界投放数据回调处理任务的接口。

    ------2、投放任务的时候,必须包含处理函数与其传入参数。

    ------3、如果这个传入参数一时间不能获得,那就给他一个期权 future。

    解决不稳定点:

    ------1、回调处理任务是可以任意多个的。使用 vector 容器包纳多个数据处理任务函数、传入参数。

    ------2、由于传入了许多参数位置的处理任务,需要等待传入的参数很多,故而需要提供一个轮询接口。

  • 回调处理函数的组合优化,QueryCallback

    ------1、期权 future 参数接口与回调处理函数组合在一起。

    ------2、提供对期权 future 参数的就绪查询接口(被异步处理器调用)

综上所述,我们可以做出 MySQL 的架构图


这么看下来

1、连接池是被观察的对象,观察者就是 MySQLConn 或者 MySQLWorker

2、连接池代理了 SQLOperation 接口

3、SQLOperation 推送了期权 future 参数给处理器(还有对应的处理函数),这样说来连接池和异步处理器是观察者模式。

相关推荐
Alphapeople1 分钟前
路径规划算法的python实现
开发语言·python·算法
重生之小比特2 分钟前
【Java SE】数组的定义与使用
java·开发语言
旋生万物7 分钟前
圈道裂痕——用 Python 验证素数分布的螺旋生成论判据
开发语言·python·数论·素数·cci·可计算数学
keyipatience21 分钟前
5种IO模型与阻塞IO,select,poll,epoll,LT和ET模式
linux·服务器·网络·数据结构·c++·算法
汉克老师24 分钟前
CSP-J 初赛(以满分为目标):第三十八课《数学与逻辑①——排列还是组合?先搞清楚“选”与“排”》
c++·csp-j·小学生·学c++编程
qeen8727 分钟前
【C++】智能指针介绍
开发语言·c++·笔记·指针
Lionel_Coder31 分钟前
matmul 总体设计
c++
hanchenxing32 分钟前
本地AI绘画网关: 用 30 行 Python 把 NVIDIA FLUX.2 Klein 接入 OpenAI 兼容客户端Python
开发语言·python·ai作画·ai绘画·nvidia
Dream Cosmos38 分钟前
C++ 中 static 关键字的作用与使用规则
linux·c++
PHP实战开发录2 小时前
PHP脚本手动能跑定时任务却失败
开发语言·php·开发