利用单利模式获取连接池实例,支持高并发,为每个连接记录存活时间,当连接总量大于最大连接数时会将时间过长的连接断开,当池子没有连接时会利用生产者线程进行生产
Connpool *Connpool::instance = nullptr;
//获得池子
Connpool *Connpool::GetInstance()
{
if (instance == nullptr)
{
std::lock_guard<std::mutex> lock(instance_mutex);
if (instance == nullptr)
{
instance = new Connpool();
}
}
return instance;
}
void Connpool::create_new_conn()
{
MySQL *p = new MySQL();
p->connect();
p->refreshAliveTime();
conn_que.push(p);
++count_con;
}
//池子初始化
Connpool::Connpool() : count_con(0)
{
for (int i = 0; i < INIT_SIZE; ++i)
{
create_new_conn();
}
/*boost::thread product(bind(&Connpool::produceConnectionTask,this));
product.detach();*/
std::thread p(bind(&Connpool::produceConnectionTask,this));
p.detach();
}
//获取一个sql连接
shared_ptr<MySQL> Connpool::GetConn()
{
unique_lock<std::mutex> lock(_mutex);
while (conn_que.empty())
{
cv_produ.notify_all();
cv_cust.wait(lock);
}
while (count_con > MAX_SIZE)
{
MySQL *p = conn_que.front();
if (p->getAliveTime() >= (MAX_TIME * 1000))
{
conn_que.pop();
count_con--;
// 调用~Connection()释放连接
delete p;
}
else
{
// 如果队头的连接没有超过_maxIdleTime,其他连接肯定没有
break;
}
}
/*if (conn_que.size() == 0)
{
if (count_con < MAX_SIZE)
{
create_new_conn();
}
else
return nullptr;
}*/
shared_ptr<MySQL> sp(conn_que.front(),
[&](MySQL *p)
{
unique_lock<std::mutex> lock(_mutex);
p->refreshAliveTime();
conn_que.push(p);
});
conn_que.pop();
return sp;
}
void Connpool::produceConnectionTask()
{
while (1)
{
unique_lock<std::mutex> lock(_mutex);
while (!conn_que.empty())
{
cv_produ.wait(lock);
}
create_new_conn();
cv_cust.notify_all();
}
}
这里的MySQL是自己对数据库操作的封装类

该博客介绍了一个使用单例模式实现的数据库连接池,支持高并发场景。连接池会记录每个连接的存活时间,并在连接总数超过最大限制时关闭超时连接。在连接池为空时,通过后台生产者线程创建新的连接。此外,还包含了一种智能指针策略,用于在获取和归还连接时刷新存活时间和维护连接队列。
6144

被折叠的 条评论
为什么被折叠?



