C++实现简易连接池(详细版)上

C++实现MySQL数据库连接池 1.连接池的介绍: 1.1应用背景: 一般的应用程序都会访问到数据库,在程序访问数据库的时候,每一次数据访问请求都必须经过下面几个步骤:建立数据库连接,打开数据库,对数据库中的数据进行操作,关闭数据库连接。而建立数据库连接和打开数据库是一件很消耗资源并且费时的工作,如果在系统中很频繁的发生这种数据库连接,必然会影响到系统的性能,甚至会导致系统的崩溃。 1.2技术思想: 在系 阅读详情

/***********************************************ConnectionPool*****************************************/

hello~大大大家好!本次主包为大家带来的是连接池学习贴,接下来我们对连接池这个小项目做一些基本的介绍,对了!关于内存池有没有兴趣呢,有的话点开此链接就可以跳转哟~话不多说,正片开始!https://mpbeta.youkuaiyun.com/mp_blog/creation/editor/148906710

一、技术点介绍

本项目不大但是可以为你带来满满干货。本项目主要涉及了MYSQL编程、单例模式设计、queue队列容器、C++11编程、CAS原子特性、生产者消费者模型、线程的同步与互斥、智能指针shared_ptr。(这些是不是看着很多,就像HR看你的简历一样……)。

二、项目背景

为了提高访问数据库的效率,我们引入了连接池。那么为什么它就可以提高访问效率呢?其实,在并发程度或者说访问量不大的场景下,连接池是发挥不了优势的。在访问数据库的过程中,客户端需要发起TCP三次握手------MYSQL验证---------响应操作--------MYSQL释放回收资源--------TCP四次挥手。这一系列过程似乎花不了多长时间,但是在高并发大量的访问场景下,频繁地TCP三次握手四次挥手、连接的验证以及回收是一种极大的浪费且似乎没有必要。那么连接池就应运而生。

服务器大量响应belike::::::::::::::::::::::::::::::::

三、连接池功能点

本项目主要实现连接池的基本功能。包括初始连接量、最大连接量、最大空闲时间和连接超时时间。

连接池运行过程

在没有引入连接池的时候,客户端发起使用mysql进行数据库的访问,其实是客户端与mysql客户端进行连接,再通过MySQL客户端与MySQL服务器进行连接,而客户对数据库的操作实质上是MySQL服务器对数据库的操作。BUT,MySQL客户端与MySQL服务器的连接包含TCP的连接与释放、MySQL之间的验证与回收,占用不少时间。

引入连接池以后,我们预先开辟一些数量的连接类,当客户端需要操作数据库的时候,MySQL客户端就从连接池取一个连接进行与MySQL服务器的连接,跳过了tcp连接与释放、MySQL的验证与回收(其实这些工作只是在初始化连接池操作了一次)。当使用完连接后再将连接放归连接池。

连接池设计功能点

1、连接池只需要一个实例,因此是单例设计模式(因为在客户端申请连接的过程中连接池是从始至终一个就够了
连接需要很多个
2、从连接池中可以获取与MySQL的连接connection
3、空闲连接connection全部放在队列中保存,因为该队列是共享资源,需要进行线程安全
4、如果初始的连接connection用完了,需要动态扩充连接,最大为maxsize
5、队列中超过最大空闲时间的连接就释放掉,最少保留初始数量的连接就足够了
6、如果队列中无可用连接,且超过连接超时时间,那么就判定连接失败
7、用户获取的连接用智能指针来管理,因为智能指针可用做到线程安全且自动回收
8、连接的生产和消费其实是生产者消费者模型

四、开始实现

gogogo~出发喽~

我们开始实现具体类的代码。

代码结构

头文件别忘了

#pragma once
#include <string>
#include <queue>
#include "Connection.h"
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <memory>
using namespace std;

connectionPool

//单例模式实现
class ConnectionPool {
public:
	static ConnectionPool* getConnectionPool();
	//用户接口,获得连接来与数据库进行交互
	shared_ptr<Connection> getConnection();
private:
	bool loadConfig();//加载配置文件(包括ip,端口号,MySQL密码等等)
	void produceconnections();//产生连接
	void cleanconnections();//清理空闲连接
	ConnectionPool();//构造函数
	
	
	//内部属性
	string _ip;//ip地址
	unsigned int _port;//端口号
	string _username;//MySQL用户名
	string _password;//MySQL密码
	string _dbname;//数据库名字
	int _initSize;//初始连接池连接数量
	int _maxSize;//最大连接池连接数量
	int _maxIdleTime;//最大空闲时间
	int _ConnectionTimeOut;//超时连接时间

	queue<Connection*> _pool;//连接池(队列存储)
	mutex _queueMutex;//互斥锁,保证线程安全
	atomic_int _currentSize;//原子型变量,记录当前连接总数,也是保证线程安全
	condition_variable _Empty;//同步信号量

};

上面各个变量已经解释的很清楚了,不用我再在外面解释了吧。如果需要记得评论一下……

配置文件(mysqlConfg.ini)

#配置文件
ip=127.0.0.1
port=3306
#这里注意修改为你的用户名
username=root
#这里注意修改为你的密码
password=200319
#这里注意修改为你的数据库名
dbname=chat

initSize=10
maxSize=1024
#单位秒
maxIdleTime=60
#单位毫秒
connectionTimeout=100

我是使用vs2022平台书写的代码,配置文件就命名为mysqConfg.ini即可

日志函数

#pragma once
#include <iostream>
#define LOG(str)\
    cout<<__FILE__<<" : "<<__LINE__<<" : "<<\
    __TIMESTAMP__<<" : "<<str<<endl;

加载配置文件函数


bool ConnectionPool::loadConfig() {
	FILE* fp = fopen("mysqlConfg.ini", "r");
	if (fp == NULL) {
		LOG("mysqlConfg.ini not found");
		return false;
	}
	while (!feof(fp)) {//如果不是文件末尾就循环执行
		char line[1024] = { 0 };//写缓冲区
		fgets(line, 1024, fp);
		string str = line;
		int idx = str.find("=",0);//找“=”的索引,找不到说明不是配置信息就接着找
		if (idx == -1) {
			continue;
		}
		int enidx = str.find("\n", idx);
		string key = str.substr(0, idx);//配置文件前面的配置信息名字
		string value = str.substr(idx + 1, enidx - idx - 1);//配置信息对应的值
        //下面是分情况讨论,得到的究竟是何方神圣
		if (key == "ip") {
			_ip = value;
		}
		else if (key == "port") {
			_port = atoi(value.c_str());
		}
		else if (key == "username") {
			_username = value;
		}
		else if (key == "password") {
			_password = value;
		}
		else if (key == "dbname") {
			_dbname = value;
		}
		else if (key == "initSize") {
			_initSize = atoi(value.c_str());
		}
		else if (key == "maxSize") {
			_maxSize = atoi(value.c_str());
		}
		else if (key == "maxIdleTime") {
			_maxIdleTime = atoi(value.c_str());
		}
		else if (key == "connectionTimeout") {
			_ConnectionTimeOut= atoi(value.c_str());
		}
		return true;
	}

}

连接池构造函数

ConnectionPool::ConnectionPool() {
	if (!loadConfig()) {
		LOG("load mysqlConfg.ini failed");
		return;
	}
	//创建初始连接
	for (int i = 0; i < _initSize; i++) {
		Connection* conn = new Connection();
		conn->connect(_ip, _port, _username, _password, _dbname);
		_pool.push(conn);
		conn->resetFreeTime();//重置空闲时间(入队列就得重置)
		_currentSize++;
	}
	//启动生产CONN线程
	thread producer(bind(&ConnectionPool::produceconnections, this));
	producer.detach();
	//启动清理线程,将超过最大空闲时间的连接清理掉
	thread cleaner(bind(&ConnectionPool::cleanconnections, this));
	cleaner.detach();


}

绑定器将成员函数和当前对象绑定,要不然这个成员方法就不能用在这里。

/*************************************************continue*************************************************/

下集预告:

实现生产者消费者线程函数

设计连接类

实现回收创建连接

……

ps:写太多了,剩下大约一半留到下一篇分解。up扛不住了,打会最后生还者去了,记住最后生还者只有第一部,没有第二部!大家加油消化,我先撤了,bye~

【C++】基于C++11的数据库连接池 在进行数据库操作的时候为了提高数据库(关系型数据库)的访问瓶颈,除了在服务器端增加缓存服务器(例如redis)缓存常用的数据之外,还可以增加连接池,来提高数据库服务器的访问效率。一般来说,对于数据库操作都是在访问数据库的时候创建连接,访问完毕断开连接。 阅读详情

相关推荐

GPS定位不准?可能是GDOP在作怪!手把手教你优化卫星几何分布

本文深入解析了GPS定位精度不佳的常见原因——几何精度因子GDOP。通过剖析卫星几何分布对定位误差的放大效应,文章提供了从理解GDOP、PDOP、HDOP等关键指标,到使用专业APP实时诊断卫星天空图,再到利用在线工具提前规划最佳定位时机的完整实战指南。旨在帮助户外爱好者、无人机飞手及专业用户主动优化卫星几何条件,从而显著提升定位可靠性。

weixin_29062823的博客 305

剖析 MySQL 数据库连接池(C++版)

上次给大家介绍了线程池的实现,这次来介绍下 Linux 下数据库连接池的实现,以大家最为熟悉的MySQL为例,因为连接池总体实现还是较为复杂的,本次以一个开源框架的数据库连接池部分为例进行讲解。首先,服务器与数据库的交互是请求响应模式,通常所使用的是TCP 长连接,而 TCP 连接需要三次握手和四次挥手,并且每次连接都需要验证账号密码等,所以连接资源属于耗时资源,可以用连接池来复用连接。

新人博主,多多关照 2215

MAC M1用户必看:UTM虚拟机安装Win11全流程避坑指南(附驱动下载)

本文为MAC M1用户提供UTM虚拟机安装Win11的完整指南,涵盖镜像准备、驱动优化及性能调优等关键步骤。特别针对TPM 2.0验证、网络连接等常见问题提供解决方案,帮助用户高效运行Windows 11 ARM版。

weixin_29204205的博客 338

C++实现数据库连接池

C++实现简易线程池

美好的事情即将发生 3980

3D视觉革命丨多相机协同拼接技术如何重塑工业检测边界

本文深入探讨了多相机协同拼接技术如何突破单台3D相机的物理局限,实现工业检测从“点面”到“立体”的无死角覆盖。通过拆解系统标定、同步融合等核心技术,并结合锂电池、长轴零件等实战案例,揭示了该技术如何以虚拟“超级视觉传感器”重塑检测边界,提升精度与效率。

weixin_29056865的博客 387

用友U8接口开发全攻略:从EAI到OpenAPI的5种方式详解(附避坑指南)

本文深度解析了用友U8系统接口开发的五种核心方式:EAI、API、OpenAPI、SQL直连与内部CO组件。文章详细对比了各方式的适用场景、优缺点及实战操作,并提供了清晰的选型决策框架与避坑指南,帮助开发者根据具体业务需求选择最高效、最稳定的集成路径。

weixin_29322855的博客 684

一文带你实现c++ socket连接池!!!

使用c++实现socket连接池

qq_44778436的博客 2817

cesium单向流动线效果

在学材质的路上一去不复返了属实是,难也难在这。还请各位大佬多多指教~

就zhei? 689

高并发服务器-连接池实现(c++版本)

数据库 连接池 mysql

hahackeris的专栏 686

给跨代引用记一本账:Java GC 的分配路径、卡表写屏障与收集器版图快速回顾

本文把 Java GC 的零散名词串成一条推理链路:从 TLAB 指针碰撞分配、逃逸分析,到 Eden、Survivor 与晋升的四条路,重点拆解卡表与写屏障如何为老年代指向新生代的引用记账,及 Minor GC 如何只扫脏卡。基于 JDK 8 实测:分散写使 Young GC 停顿涨 10~15 倍,条件卡标记消除卡表伪共享,计数循环让 System.gc 等待 2.7 秒,Survivor 过小使晋升量增加约 400 倍。文末梳理 JDK 8 到 27 的收集器演进、选型路径与排查顺序。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 17万+

【离线OCR】微信离线实现图片OCR文本和表格识别

基于微信本地OCR引擎(由最新版微信自动安装)。通过Python对其官方调用逻辑进行完整翻译和封装,使开发者可以用简单的API调用其强大的OCR功能。

专注于医院数据分析技术与系统开发的创作与分享。 2623

C++手撕连接池

用c++写一个数据库连接池数据库连接池是为了提高数据库连接的性能,进行连接复用对于复杂数据库进行大量引用的场景下就会出现访问瓶颈常见的两种解决方法就是:为了减少磁盘 I/O的次数,在数据库和服务器的应用中间加一层 缓存数据库(例如:Redis、Memcache);或者就是增加连接池,来减少高并发情况下大量 TCP三次握手、MySQL Server连接认证、MySQL Server关闭连接回收资源和TCP四次挥手 所耗费的性能。

oorik的博客 1026

2015年高教社杯全国大学生数学建模竞赛 A 题:《太阳影子定位》真题解析与 MATLAB 解决方案

🏆 本文已收录于专栏:《滚雪球学数学建模(含历年真题)》,持续更新最新及历年数学建模竞赛资料,每篇内容力求做到“问题讲透、模型讲清、代码可用、论文可参考”,帮助你从零开始逐步建立完整的数学建模知识体系。

**My Coding Family** 1357

学习笔记:MySQL连接池原理及C++实现

MySQL连接池技术通过复用数据库连接解决高并发场景下的性能问题。文章介绍了连接池的实现原理,包括同步/异步两种模式:同步连接池在初始化阶段保证顺序执行,异步连接池通过队列实现并发处理。核心组件包括连接池管理类MySQLConnPool、连接类MySQLConn、工作线程MySQLWorker和SQL操作类SQLOperation,其中使用future/promise机制实现主线程与数据库的返回值传递。该技术通过减少连接创建开销和资源占用,显著提升了数据库访问效率(完整代码见Github)。

djdihfsjw的博客 764

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

C++实现简易连接池(详细版)下

本文详细介绍了基于C++的MySQL数据库连接池实现方案。通过生产者-消费者模型,实现了连接的动态管理,包括:1)生产者线程负责创建新连接;2)消费者线程获取连接并使用后自动归还;3)清理线程定期回收空闲连接。采用智能指针结合自定义删除器确保连接正确回收,使用互斥锁和条件变量保证线程安全。完整代码实现了连接池的单例模式、MySQL操作封装和配置文件读取等功能,支持初始化连接数、最大连接数、空闲超时等参数配置。该方案有效提高了数据库连接复用率,降低了频繁创建/销毁连接的开销。

csdddd55的博客 637

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++实现简易数据库连接池的研究

数据库连接池是指,在服务器程序未和客户端通讯时,就提前创建好一定数量的数据库连接并放入缓冲池中;当服务器工作线程需要请求建立数据库连接时,就可以直接从缓冲池中“拿出”建立好的连接来用,用完后将该连接放回池中(动态绑定机制),连接本身不会中断。数据库连接池负责分配,管理和释放数据库连接,它允许服务器程序重复使用一个现有的数据库连接,而不是重新建立一个。(即连接池中的连接是公共的,谁都能用,你用完我可以接着用)当线程向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。

qq_46027463的博客 2240

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【MySQL】MySQL连接池原理与简易网站数据流动是如何进行

实际上在开发的时候把表结构各方面设计好了,接下来要做的不是写各种各样的sql,在做开发的时候,是先要连接数据库的。而我们会发现连接数据库的时候每一次连的都是先创建数据库对象然后connet用完之后要把释放把连接关掉,这种执行一条sql这种就把连接关了这是一种短连接,并且挺浪费的。所以mysql在网站和数据库之间,除了一些缓存方面的技术,还有一个在编码层面上的技术叫做 连接池。

fight_p的博客 4370

C++ 实现 MySQL 连接池

C++ 实现 MySQL 连接池 复习

C/C++ 1226

【C++实现】 数据库连接池

mysql连接池实现,连接对象模块Connection模块,这个模块负责实现连接mysql的部分,进行数据库增删查改接口的封装。Connection初始化连接对象connect 绑定ip,端口,用户,密码,库名称update 传入string sql,进行实施query 进行select查询,这里用不到refreshAliveTime 设置每一个连接对象在队列里面呆着的起始时间getAliveTime 获取对象从refreshAliveTime到如今的时间,单位ms连接池模块模块。

jhao的博客 2267

项目——C++实现数据库连接池

前言 在学习Mysql的时候,我们都有这个常识:对于DB的操作,其实本质上是对于磁盘的操作,如果对于DB的访问次数过多,其实就是涉及了大量的磁盘IO,这就会导致MYsql出现性能上的瓶颈。 项目背景 为了提高Mysql数据库的访问瓶颈,常用的方法有如下两个: 在服务器端增加缓存服务器缓存常用的数据(例如redis) 增加连接池,来提高MYsql Server的访问效率,在高并发的情况下,每一个用户大量的TCP三次握手。Mysql Server的连接认证,Mysql Server关闭连接回收资源和TCP四次

qq_44824574的博客 4414

C++ 如何实现mysql连接池?

网上大部分MySQL连接池实现都是玩具demo级别的,要么功能简陋,要么bug一堆,根本不能用于生产环境。作为一个写了好几年C++后端的程序员,我来详细聊聊如何实现一个真正可用的MySQL连接池。线程池卖爆了!这次直接上"王炸"——手撸4200行MySQL连接池,8天带你搞定后端核心组件!先说说痛点。直接连接MySQL的问题: 性能对比数据:这就是为什么所有互联网公司都必须用连接池的原因。 设计要点: 3. 智能重连机制 这是大多数demo实现忽略的关键点: 4. 健康检查线程 现有开源方案的问题 很多人

Henry313的博客 1250

C++版mysql数据库连接池

手写数据库连接池 文章目录手写数据库连接池关键技术点项目背景连接池功能点介绍MySQL Server参数介绍功能实现设计连接池代码及详细介绍连接池构造函数获取单例生产者线程消费者线程接口定时线程(回收连接)压力测试测试代码和配置文件:Connection 操作代码 返回的 是一个含connection的shared_ptr对象 关键技术点 MySQL数据库编程、单例模式、queue队列容器、C++11多线程编程、线程互斥、线程同步通信(mutex、条件变量)和 unique_lock、基于CAS的原子整

qq_53111905的博客 2347

突破C++网络性能瓶颈:cpp-httplib连接池设计与实现指南

在高并发的C++网络应用中,频繁创建和销毁HTTP连接会导致严重的性能损耗。cpp-httplib作为一款轻量级的HTTP客户端/服务器库,通过精心设计的连接池机制有效解决了这一问题。本文将深入剖析cpp-httplib连接池的实现原理,提供实用的配置指南,并通过实例展示如何将吞吐量提升300%以上。 ## 连接池核心配置参数解析 cpp-httplib通过一系列预编译宏定义了连接池的核心行为...

gitblog_00255的博客 607
上一篇: 离散数学-命题逻辑学习笔记-2
下一篇: 离散数学-命题逻辑学习笔记-3
厚切薯片
博客等级 码龄5年 89粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值