【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 参数给处理器(还有对应的处理函数),这样说来连接池和异步处理器是观察者模式。

相关推荐
为何创造硅基生物9 小时前
C语言 结构体内存对齐规则(通俗易懂版)
c语言·开发语言
吃好睡好便好9 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
星寂樱易李9 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
仰泳之鹅9 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
rising start9 小时前
二、全面理解MySQL架构
mysql·架构
之歆9 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
bqq1986102610 小时前
MySQL性能优化
mysql·mysql优化
于小猿Sup10 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
cen__y11 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
AI人工智能+电脑小能手11 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm