C++_手写_数据库连接池

C++_手写数据库连接池

关键技术点

MySQL数据库编程、单例模式、queue队列容器、C++11多线程编程、线程互斥、线程同步通信和 unique_lock、基于CAS的原子整形、智能指针shared_ptr、lambda表达式、生产者-消费者线程模型

连接池的主要功能点

  1. 单例模式:因为连接池只需要一个实例

  2. 从ConnectionPool中可以获取和MySQL的连接Connection

  3. 空闲连接Connection全部维护在一个线程安全的Connection队列中,使用线程互斥锁保证队列的线程安全

  4. 如果Connection队列为空,还需要再获取连接,此时需要动态创建连接,上限数量是maxSize

  5. 队列中空闲连接时间超过maxIdleTime的就要被释放掉,只保留初始的initSize个连接就可以了,这个功能点可定需要放在独立的线程中去做

  6. 如果Connection队列为空,而此时连接的数量已达到上限maxSize,那么等待connectionTineout时间,如果还获取不到空闲的连接,那么获取连接失败,此处从Connection队列获取空闲连接,可以使用带超时时间的mutex互斥锁来实现连接超时时间

  7. 用户获取的连接用shared_ptr智能指针来管理,用lambda表达式定制连接释放的功能(不真正释放连接,而是把连接归还到连接池中)

  8. 连接的生产和连接的消费采用生产者-消费者线程模型来设计,使用了线程间的同步通信机制条件变量和互斥锁

核心代码分享

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%

(模拟多个用户1000+同时接入数据库的情况)

posted @   Espre-sso  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示