程序类型: C++连接池抽象类
适用平台: Linux
适用数据库: Mysql(亲测可用), Redis(亲测可用), Oracle(亲测可用)
适合读者: C/C++初学者学习交流使用
使用注意: 此类属于C++抽象类, 必须被继承后使用
简单介绍: 这段时间开发服务器涉及到redis和mysql数据库连接池, 在网上翻阅资料基本上都是针对性的,比如针对mysql设计的mysql连接池, 针对redis设计的redis连接池, 自己想了想, 都是连接池, 为啥不能写一个公用的方法呢 , 写一个抽象类, 供其他数据库连接池继承, 这样也就符合了C++的多态思想(这边纯属装个<B>, 高手请绕道)
思路介绍:
- 首先有连接池,必须先创造一个由若干个连接组成的连接池来管理, 并指定最大和最小连接数
- 连接池创造好了,当然要提供给外部获取和返还的方法
- 在外部调用过多时, 不够的需要创造新的, 这时候就会出现调用完成反还后面用不到, 连接池内部出现太多的空闲连接白消耗资源,这时候就需要管理者来管理这些冗余的连接
- 创造管理者子线程,用来定期监控空闲线程和定期清理那些未知原因导致的连接与数据库断开的连接
功能介绍:
1. 需要子类重写的受保护的纯虚函数(protected)
//创建一个连接:纯虚函数, 子类必须要实现
virtual void * createLink() = 0;
//销毁指定的连接:纯虚函数
virtual void v_destroyLink(void *link) = 0;
//检测连接是否可以用:通过一个不影响数据库的请求检测,比如Mysql的mysql_ping(MYSQL* con)
virtual bool isUsed(void *link) = 0;
[注意] 获得连接和反还连接用的都是void*, 此处是因为当前类为抽象类, 不是具体的数据库连接池, 所有的连接对象类型都未知, 调用如下:
//比如这是Redis的连接池伪代码
//实例继承连接池的Redis连接池对象
RedisPool redis;
//将获得的redis连接强转成Redis对象
Redis *red = (Redis*)redis.getLink();
2. 介绍公共成员函数
//构造函数
LinkPool();
//获得错误码
LinkPool::ErrOpt errNo();
//初始化连接池
//(minLinkNum:连接池最小连接数, maxLinkNum:连接池最大连接数,checkFreeLinkSecs:检查空闲链接秒数)
void createLinkPool(int minLinkNum, int maxLinkNum, int checkFreeLinkSecs = 10);
//销毁一个连接
void destroyLink(void *link);
//获得一个连接
void * getLink();
//返还一个连接到连接池
void backLink(void *link);
//销毁连接池:析构时自动调用
void destroyLinkPool();
//虚析构:目的是为了析构子类时,析构父类
virtual ~LinkPool();
3. 介绍私有成员变量
//线程锁:用来多线程操作的安全,使用静态方便调用
static pthread_rwlock_t *g_lock;
//连接池列表:当前连接池可用连接的链表
list<void*> m_linkList;
//忙碌的连接列表:已被取出的连接链表
list<void*> m_busyLinkList;
//最大连接数:连接池容纳的最大连接数
int m_maxLinkNum = 0;
//最小连接数:连接池容纳的最小连接数
int m_minLinkNum = 0;
//检查连接秒数:检查是否存在空闲连接的频率
int m_checkFreeLinkSecs = 0;
//存管理线程tid:管理者子线程id,用来销毁线程池时进行回收
pthread_t m_adjust_tid;
//忙碌连接数:当前忙碌的连接数(已被取出的)
int m_busyLinkNum = 0;
//空闲链接数:当前空闲的连接数(未被取出的)
int m_freeLinkNum = 0;
//错误码:出错时进行赋值(枚举)
LinkPool::ErrOpt m_errno;
//是否销毁:是否销毁,管理者线程执行无限循环的判断条件, 销毁则自动结束管理者线程
bool m_isDestory = false;
4. 错误类型