#include "stdafx.h"
|
#include "ConnectionPool.h"
|
|
#include <fstream>
|
#include <iostream>
|
#include <thread>
|
|
ConnectionPool* ConnectionPool::getInstance() {
|
static ConnectionPool connPool;
|
return &connPool;
|
}
|
|
ConnectionPool::ConnectionPool() {
|
// ¼ÓÔØÅäÖÃÎļþ
|
if (!parseJsonFile()) {
|
std::cout << "parseJsonFile is failed!" << std::endl;
|
return;
|
}
|
for ( int i = 0 ; i < m_min_conn ; i++ ) {
|
addConnection( );
|
}
|
// ´´½¨Ò»¸öỊ̈߳¬¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Á¬½ÓÊý²»×ã¾ÍÔÙ¼ÌÐø´´½¨
|
std::thread producer(&ConnectionPool::produce, this);
|
// ¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Èç¹ûÓÐÌ«¶à¿ÕÏеÃÏß³Ì £¬ÄÇô¾Í¶ÔÆä½øÐÐÏú»Ù
|
std::thread recycler( &ConnectionPool::recycle, this);
|
|
// Ï̷߳ÖÀë
|
producer.detach();
|
recycler.detach();
|
}
|
|
bool ConnectionPool::parseJsonFile() {
|
|
/*std::ifstream ifs("dbconf.json");
|
Reader rd;
|
Value root;
|
rd.parse(ifs, root);
|
if ( root.isObject( ) ) {
|
m_ip = root["ip"].asString();
|
m_port = root["port"].asInt();
|
m_userName = root["userName"].asString();
|
m_passwd = root["password"].asString();
|
m_db = root["dbName"].asString();
|
m_min_conn = root["minSize"].asInt();
|
m_max_conn = root["maxSize"].asInt();
|
max_del_time = root["maxDleTime"].asInt();
|
m_timeout = root["timeout"].asInt();
|
return true;
|
}*/
|
return false;
|
}
|
|
void ConnectionPool::description() {
|
std::cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
|
<< m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". "
|
<< max_del_time << std::endl;
|
}
|
|
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->connect( m_ip, m_userName, m_passwd, m_db, m_port ) ) {
|
std::cout << "ConnectionPool connect to mysql is failed!" << std::endl;
|
delete conn;
|
return;
|
}
|
conn->refreshActiveTime( );
|
m_connkQueue.push(conn);
|
m_cond.notify_one(); // »½ÐÑÒ»¸öÏß³Ì
|
}
|
|
void ConnectionPool::produce(){
|
while (true) {
|
std::unique_lock<std::mutex> lock(m_mutex);
|
while (m_connkQueue.size() >= m_min_conn) { // Á¬½Ó¶ÓÁеÄÊýÁ¿´óÓÚ×îСµÄÁ¬½ÓÊý
|
m_cond.wait(lock);
|
}
|
addConnection();
|
}
|
}
|
|
// ɾ³ý¿ÕÏÐÁ¬½Ó
|
void ConnectionPool::recycle() {
|
while ( true ) {
|
std::this_thread::sleep_for( std::chrono::milliseconds(500)); // ÐÝÃß500 ms
|
std::unique_lock<std::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;
|
}
|
}
|
}
|
}
|
|
std::shared_ptr<MysqlConn> ConnectionPool::getMysqlConn() {
|
|
std::unique_lock<std::mutex>lock(m_mutex);
|
while ( m_connkQueue.empty()) {
|
// Èç¹ûµÈ´ýÒ»¶Îʱ¼äºó,¶ÓÁл¹ÊÇΪ¿Õ,·µ»ØÒ»¸ö null
|
if ( std::cv_status::timeout == m_cond.wait_for(lock, std::chrono::milliseconds(m_timeout)) ) {
|
if( m_connkQueue.empty( ) ) return nullptr;
|
}
|
}
|
std::shared_ptr<MysqlConn> connPtr(std::move(m_connkQueue.front()), [this](MysqlConn* conn) {
|
std::unique_lock <std::mutex>lock(m_mutex) ;
|
conn->refreshActiveTime();
|
m_connkQueue.push(conn);
|
});
|
m_connkQueue.pop();
|
m_cond.notify_one(); // »½ÐÑ×èÈûµÄÉú²úÕßÏß³Ì,¿ªÊ¼Éú²ú
|
return connPtr;
|
}
|