C++_手写_数据库连接池
关键技术点
连接池的主要功能点
-
单例模式:因为连接池只需要一个实例
-
从ConnectionPool中可以获取和MySQL的连接Connection
-
空闲连接Connection全部维护在一个线程安全的Connection队列中,使用线程互斥锁保证队列的线程安全
-
如果Connection队列为空,还需要再获取连接,此时需要动态创建连接,上限数量是maxSize
-
队列中空闲连接时间超过maxIdleTime的就要被释放掉,只保留初始的initSize个连接就可以了,这个功能点可定需要放在独立的线程中去做
-
如果Connection队列为空,而此时连接的数量已达到上限maxSize,那么等待connectionTineout时间,如果还获取不到空闲的连接,那么获取连接失败,此处从Connection队列获取空闲连接,可以使用带超时时间的mutex互斥锁来实现连接超时时间
-
用户获取的连接用shared_ptr智能指针来管理,用lambda表达式定制连接释放的功能(不真正释放连接,而是把连接归还到连接池中)
-
连接的生产和连接的消费采用生产者-消费者线程模型来设计,使用了线程间的同步通信机制条件变量和互斥锁
核心代码分享
ConnectionPool.cpp和 ConnectionPool.h:连接池代码实现
Connection.cpp和 Connection.h:数据库操作代码、增删改查代码实现
构造函数私有化,提供一个 getConnectionPool接口来构造唯一的数据库连接池
getConnectionPool 是一个线程安全的懒汉单例函数接口
ConnectionPool* ConnectionPool::getConnectionPool()
{
static ConnectionPool pool; // lock和unlock
return &pool;
}
将数据库连接需要的ip、port、username、password、dbname等封装到了mysql.ini文件中
bool loadConfigFile(); 这个接口可以从配置文件中加载配置项
ConnectionPool::ConnectionPool()构造函数中,创建2个线程,一个用于连接生产者,另一个用于定时扫描超时,进行对于超时的连接回收。
// 启动一个新的线程,作为连接的生产者 linux thread => pthread_create
thread produce(std::bind(&ConnectionPool::produceConnectionTask, this));
produce.detach();
// 启动一个新的定时线程,扫描超过maxIdleTime时间的空闲连接,进行对于的连接回收
thread scanner(std::bind(&ConnectionPool::scannerConnectionTask, this));
scanner.detach();
将这两个线程detach,从主线程分离
测试结果
使用带连接池的数据库访问 比 使用普通的数据库访问操作 大约用时少50%
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了