#include "stdafx.h"
|
#include "ConnectionPool.h"
|
|
|
ConnectionPool::ConnectionPool() {
|
|
|
m_min_conn = 5; // ¼ÙÉè×îСÁ¬½ÓÊýΪ 5
|
m_max_conn = 10; // ¼ÙÉè×î´óÁ¬½ÓÊýΪ 10
|
m_timeout = 1000; // ¼ÙÉèÁ¬½Ó³¬Ê±Ê±¼äΪ 1000 ºÁÃë
|
max_del_time = 60000; // ¼ÙÉè×î´ó¿ÕÏÐʱ¼äΪ 60000 ºÁÃë
|
|
for (int i = 0; i < m_min_conn; i++) {
|
addConnection();
|
}
|
// ´´½¨Ò»¸öỊ̈߳¬¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Á¬½ÓÊý²»×ã¾ÍÔÙ¼ÌÐø´´½¨
|
thread producer(&ConnectionPool::produce, this);
|
// ¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Èç¹ûÓÐÌ«¶à¿ÕÏеÃÏß³Ì £¬ÄÇô¾Í¶ÔÆä½øÐÐÏú»Ù
|
thread recycler(&ConnectionPool::recycle, this);
|
|
// Ï̷߳ÖÀë
|
producer.detach();
|
recycler.detach();
|
}
|
|
|
ConnectionPool::~ConnectionPool() {
|
while (!m_connkQueue.empty()) {
|
MysqlConn* conn = m_connkQueue.front();
|
m_connkQueue.pop();
|
delete conn;
|
}
|
}
|
|
void ConnectionPool::addConnection() {
|
MysqlConn* conn = new MysqlConn();
|
if (!conn->isConnected()) {
|
cout << "ConnectionPool connect to mysql is failed!" << endl;
|
delete conn;
|
return;
|
}
|
conn->refreshActiveTime();
|
m_connkQueue.push(conn);
|
m_cond.notify_one(); // »½ÐÑÒ»¸öÏß³Ì
|
}
|
|
void ConnectionPool::produce() {
|
while (true) {
|
unique_lock<mutex> lock(m_mutex);
|
while (m_connkQueue.size() >= m_min_conn) { // Á¬½Ó¶ÓÁеÄÊýÁ¿´óÓÚ×îСµÄÁ¬½ÓÊý
|
m_cond.wait(lock);
|
}
|
addConnection();
|
}
|
}
|
|
// ɾ³ý¿ÕÏÐÁ¬½Ó
|
void ConnectionPool::recycle() {
|
while (true) {
|
this_thread::sleep_for(chrono::milliseconds(500)); // ÐÝÃß 500 ms
|
unique_lock<mutex> lock(m_mutex);
|
while (m_connkQueue.size() > m_min_conn) {
|
MysqlConn* conn = m_connkQueue.front();
|
if (conn->getActiveTime() >= max_del_time) {
|
m_connkQueue.pop();
|
delete conn;
|
}
|
else {
|
break;
|
}
|
}
|
}
|
}
|
|
shared_ptr<MysqlConn> ConnectionPool::getMysqlConn() {
|
unique_lock<mutex> lock(m_mutex);
|
while (m_connkQueue.empty()) {
|
// Èç¹ûµÈ´ýÒ»¶Îʱ¼äºó,¶ÓÁл¹ÊÇΪ¿Õ,·µ»ØÒ»¸ö null
|
if (cv_status::timeout == m_cond.wait_for(lock, chrono::milliseconds(m_timeout))) {
|
if (m_connkQueue.empty()) return nullptr;
|
}
|
}
|
shared_ptr<MysqlConn> connPtr(move(m_connkQueue.front()), [this](MysqlConn* conn) {
|
unique_lock<mutex> lock(m_mutex);
|
conn->refreshActiveTime();
|
m_connkQueue.push(conn);
|
});
|
m_connkQueue.pop();
|
m_cond.notify_one(); // »½ÐÑ×èÈûµÄÉú²úÕßÏß³Ì,¿ªÊ¼Éú²ú
|
return connPtr;
|
}
|
void ConnectionPool::description() {
|
cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
|
<< m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". "
|
<< max_del_time << endl;
|
}
|
|
ConnectionPool* ConnectionPool::getInstance() {
|
static ConnectionPool connPool;
|
return &connPool;
|
}
|