C++_手写数据库连接池
关键技术点
MySQL数据库编程、单例模式、queue队列容器、C++11多线程编程、线程互斥、线程同步通信和 unique_lock、基于CAS的原子整形、智能指针shared_ptr、lambda表达式、生产者-消费者线程模型
连接池的主要功能点
-
单例模式:因为连接池只需要一个实例
-
从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%
(模拟多个用户1000+同时接入数据库的情况)
标签:数据库,ConnectionPool,C++,Connection,线程,手写,连接,连接池 From: https://www.cnblogs.com/espgod/p/17680194.html