生产者
:生产连接消费者
: 使用数据库的客户端
- 连接池内
连接过多
- 时间戳记录连接的空闲时间,若空闲时间大于指定时长,就销毁掉该连接
- 连接池内
连接过少
- 直接新增连接
互斥锁、条件变量
(由于模型逻辑简单,所以生产者和消费者共用一把互斥锁
和一个条件变量
,不影响线程池逻辑)队列
:存储数据库连接单例模式
(懒汉模式
中注意线程安全问题,要加锁,利用C++11中的static
来实现)- 线程池对象作为静态局部变量:生命周期为整个程序周期,在线程池对外的接口
static getConnectionPool
函数中声明,并且由于C++11特性,该声明只会有一次 - 线程池对象作为
私有成员
- 线程池对象作为静态局部变量:生命周期为整个程序周期,在线程池对外的接口
- 通过
jason
来实现数据库连接信息的传递(通过vcpkg
包管理jasoncpp
库) 回收线程
有两种方式- 函数控制回收: 当使用连接的线程完成时,调用该函数将连接放回队列中
shared_ptr<T>
自动回收连接: 将回收连接的逻辑写在共享指针的删除器
中
使用连接池 | 不使用连接池 | |
---|---|---|
单线程 | 33673ms | 51257ms |
多线程 | 10302ms | 47423ms |
- 在多线程+不使用连接池的情况下,会出现插入丢失,这是因为多个线程同时登陆mysql,mysql会拒绝某些连接,这时需要在开启多线程之前,预连接数据即可
- 修改数据库编码格式要使用
utf8
而不是utf-8
- 在遇到程序bug时,不要直接用gdb去debug,要先用DBMS测试一下数据库是否能连接上,不然的话直接去debug花费大量时间在其他地方最后才发现是数据库没连接上。
- 在wsl中使用mysql,记得要关闭数据库在关机!(不然下次数据库坏了哭都来不及)