MySQL连接池的实现

时间:2022-09-19 23:14:54
class connect_pool
{
public:
connect_pool();
~connect_pool();

public:
MYSQL *get_connection();
int free_connection(MYSQL *mysql);

private:
int init(string db_server_ip, string user, string password, string db_name, unsigned int db_server_port, unsigned int pool_size);
int connect();

private:
unsigned int m_cur_connect;
string m_db_server_ip;
string m_user;
string m_password;
string m_db_name;
unsigned int m_db_server_port;
thread_lock m_thread_lock;
deque<MYSQL*> m_deque_conn;
};
connect_pool::connect_pool()
{
deque<MYSQL*>().swap(m_deque_conn);
config_file_oper config_file("server_config.conf");
string db_server_ip = config_file.get_config_value("db_server_ip");
string user = config_file.get_config_value("user");
string password = config_file.get_config_value("password");
string db_name = config_file.get_config_value("db_name");
unsigned int db_server_port = atoi(config_file.get_config_value("db_server_port"));
unsigned int pool_size = atoi(config_file.get_config_value("connect_pool_size"));
init(db_server_ip, user, password, db_name, db_server_port, pool_size);
}

connect_pool::~connect_pool()
{
deque<MYSQL*>::iterator it = m_deque_conn.begin();
for (; it != m_deque_conn.end(); it++)
{
if (NULL != *it)
{
mysql_close(*it);
*it = NULL;
}
}
deque<MYSQL*>().swap(m_deque_conn);
}

int connect_pool::init(string db_server_ip, string user, string password, string db_name, unsigned int db_server_port, unsigned int pool_size)
{
int ret = 1;
m_cur_connect = 0;
m_db_server_ip = db_server_ip;
m_db_server_port = db_server_port;
m_user = user;
m_password = password;
m_db_name = db_name;
for (unsigned int i = 0; i < pool_size; i++)
{
if (connect() == 0)
{
m_cur_connect++;
}
}
if (m_cur_connect == pool_size)
{
ret = 0;
}
return ret;
}

int connect_pool::connect()
{
int ret = 0;
MYSQL *mysql = mysql_init(NULL);
int value = true;
mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&value);//设置断线重连
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8");//设置字符集
MYSQL *status = mysql_real_connect(mysql, m_db_server_ip.c_str(), m_user.c_str(), m_password.c_str(), m_db_name.c_str(), m_db_server_port, NULL, CLIENT_MULTI_STATEMENTS);
if (NULL == status)
{
ret = 1;
}
else
{
m_deque_conn.push_back(mysql);
}
return ret;
}

MYSQL *connect_pool::get_connection()
{
m_thread_lock.lock();
while (m_deque_conn.empty())
{
m_thread_lock.wait();
}
MYSQL *mysql = m_deque_conn.front();
m_deque_conn.pop_front();
m_thread_lock.unlock();
return mysql;
}

int connect_pool::free_connection(MYSQL *mysql)
{
if(NULL == mysql)
{
return 0;
}
int ret = 0;
m_thread_lock.lock();
deque<MYSQL*>::iterator it = m_deque_conn.begin();
//判断容器中是否已存在,避免重复归还
for (; it != m_deque_conn.end(); it++)
{
if (mysql == *it)
{
break;
}
}
if (it == m_deque_conn.end())
{
m_deque_conn.push_back(mysql);
m_thread_lock.signal();
}
else
{
ret = 1;
}
m_thread_lock.unlock();
return ret;
}