简单mysql连接池
2016-03-13 15:47
501 查看
原文链接:http://blog.sina.com.cn/s/blog_49f761940100nv39.html
原文链接:
http://blog.csdn.net/midle110/article/details/19564463
版本一:
连接池为了解决频繁的创建、销毁所带来的系统开销。
简而言之,就是 自己先创建一定量的连接,然后在需要的时候取出一条连接使用。
当然如果你只有一个线程连接数据库,而且不是实时返回结果,那么你完全不必用连接池。
想一下网络大型游戏服务器,你就明白为什么需要连接池了。
自己敲代码写了一个简单的类,实现连接池,虽然没有mysql++那么强大,但是还是自己有收获。
Csqlpool.h 头文件实现如下:
[cpp] view
plain copy
#pragma once
#include <WinSock2.h>
#include <mysql.h>
#include <list>
#pragma comment( lib , "libmysql.lib" )
using namespace std;
class Csqlpool
{
public:
~Csqlpool(void);
static Csqlpool *GetSqlPool();
bool IniSqlPool( const char *host , const char *name , const char *pwd , unsigned int port , unsigned int conMax ); //初始化连接池
bool SelectDB( MYSQL *sql, const char *DB); //选择数据库
MYSQL *GetConnect(); // 获取连接
void RelConnect(MYSQL *sql) ; // 释放连接
MYSQL_RES* GetQuery( MYSQL *sql , const char *query); //mysql操作 增删查改
void RelQuery(MYSQL_RES *res); //释放MYSQL_RES资源
bool Query(MYSQL *sql , const char *query); //增、删、改操作
protected:
Csqlpool(void);
private:
list<MYSQL *> m_sql_free; //空闲连接
static Csqlpool *pSqlPool;
CRITICAL_SECTION m_session; //获取空闲线程
};
Csqlpool.cpp 实现如下:
[cpp] view
plain copy
#include "StdAfx.h"
#include "Csqlpool.h"
Csqlpool *Csqlpool::pSqlPool = NULL;
Csqlpool::Csqlpool(void)
{
InitializeCriticalSection( &m_session );
}
Csqlpool::~Csqlpool(void)
{
while ( m_sql_free.size() )
{
mysql_close( m_sql_free.front() );
m_sql_free.pop_front();
}
DeleteCriticalSection(&m_session);
}
Csqlpool* Csqlpool::GetSqlPool()
{
if ( pSqlPool == NULL )
{
return new Csqlpool;
}
return pSqlPool;
}
bool Csqlpool::IniSqlPool( const char *host ,const char *name , const char *pwd , unsigned int port , unsigned int conMax ) //初始化连接池
{
int nsum = 0 ;
for (unsigned int i = 0 ; i < conMax ;++i )
{
MYSQL *pmysql;
pmysql = mysql_init( (MYSQL*)NULL );
if ( pmysql != NULL )
{
if ( mysql_real_connect( pmysql , host , name , pwd , NULL , 3306 , NULL , 0 ) )
{
m_sql_free.push_back(pmysql);
}
else
{
if ( nsum++ == 100 )
{
return false;
}
continue;
}
}
continue;
}
return true;
}
bool Csqlpool::SelectDB( MYSQL *sql, const char *DB) //选择数据库
{
if(mysql_select_db(sql , DB))
{
return false;
}
return true;
}
MYSQL* Csqlpool::GetConnect() // 获取连接
{
if ( m_sql_free.size() )
{
EnterCriticalSection(&m_session);
MYSQL *mysql = m_sql_free.front();
m_sql_free.pop_front();
LeaveCriticalSection(&m_session);
return mysql;
}
else
return NULL;
}
void Csqlpool::RelConnect(MYSQL *sql) // 释放连接
{
EnterCriticalSection(&m_session);
m_sql_free.push_back(sql);
LeaveCriticalSection(&m_session);
}
MYSQL_RES* Csqlpool::GetQuery( MYSQL *sql , const char *query) //查询操作
{
if ( mysql_query( sql , query ) == 0 )
{
return mysql_store_result( sql );
}
else
return NULL;
}
void Csqlpool::RelQuery(MYSQL_RES *res) //mysql_res release
{
mysql_free_result(res);
}
bool Csqlpool::Query(MYSQL *sql , const char *query) //增、删、改操作
{
if ( mysql_query( sql , query ) )
{
return false;
}
return true;
}
testsqlpool.cpp 测试文件实现如下:
[cpp] view
plain copy
// testsqlpool.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Csqlpool.h"
#include <iostream>
using namespace std;
Csqlpool *psql = Csqlpool::GetSqlPool();
DWORD WINAPI ThreadProc( LPVOID lpParameter);
int _tmain(int argc, _TCHAR* argv[])
{
if(!psql->IniSqlPool("127.0.0.1" , "root" ,"123",3306,10))
{
cout<<"连接错误"<<endl;
}
HANDLE phan[2] ;
DWORD threadid[2];
int n1 = 0, n2 = 100;;
phan[0] = CreateThread( NULL , 0 , ThreadProc , &n1 , 0 , &threadid[0] );
phan[1] = CreateThread( NULL , 0 , ThreadProc , &n2 , 0 , &threadid[1] );
WaitForMultipleObjects( 2 , phan , true , INFINITE );
CloseHandle(phan[0]);
CloseHandle(phan[1]);
return 0;
}
DWORD WINAPI ThreadProc( LPVOID lpParameter)
{
int index = *(int *)lpParameter ;
int i = 1;
MYSQL *sql = psql->GetConnect();
string stemp = "insert into actor( actor_id , first_name , last_name,last_update )values(\"";
string strsql;
char str[10];
if ( psql->SelectDB(sql , "sakila") )
{
while ( i != 100 )
{
sprintf( str , "%d" , i+index );
strsql = stemp ;
strsql += str;
strsql += "\",\"0\",\"0\",\"0\")";
if(!sql)
return 0;
if(!psql->Query( sql ,strsql.c_str() ))
{
cout<<"add false"<<endl;
}
++i;
}
psql->RelConnect(sql);
}
return 0;
}
版本二:
一、头文件【存为:connPool.h】
#ifndef __CONNECTION_POOL_H__
#define __CONNECTION_POOL_H__
#include "mutex.h"
#define MYSQL_CONN_NUM_MAX_VALUE 500
using namespace std;
enum _USE_STATUS
{
US_USE = 0,
US_IDLE = 1
};
typedef struct _sConStatus
{
void* connAddr;
int useStatus;
}sConStatus;
class CConnPool
{
public:
CConnPool();
~CConnPool();
public:
int Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum);//connection pool init
void* getOneConn();//get a connection
void retOneConn(void* pMysql);// return a connection
void checkConn(); // check the connection if is alive
void* createOneConn();
public:
char m_szMysqlIp[100];
char m_szUser[100];
char m_szPwd[100];
char m_szDbName[100];
int m_nMysqlPort;
int m_nConnNum;
public:
CMutex m_sMutex;
vector<void*> m_vectorConn;
map<void*, int> m_mapVI;
map<void*, void*> m_mapMysqlScs;
};
class CConnPoolV2
{
public:
CConnPoolV2();
~CConnPoolV2();
public:
int Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum);//connection pool init
void* getOneConn(); //从连接池取一个连接
void retOneConn(void* pConn);// 连接用完了,把它放回连接池。以便其他人用。
void checkConn(); // check the connection if is alive
void* createOneConn();
private:
string m_strMysqlIp;
string m_strUser;
string m_strPwd;
string m_strDbName;
int m_nMysqlPort;
int m_nConnNum;
private:
CMutex m_sMutex;
vector<void*> m_vectorConn;
map<void*, int> m_mapVI; // 从连接的地址,快速找到索引,便于存放到m_vectorConn中。
};
#endif
二、源码【存为:connPool.cpp】
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <time.h>
#include <iostream>
#include <memory>
#include <string>
#include <map>
#include <vector>
#include "mysql.h"
#include "encapsulation_mysql.h"
#include "connPool.h"
#include "mutex.h"
using namespace std;
using namespace EncapMysql;
CConnPool::CConnPool( )
{
}
CConnPool::~CConnPool( )
{
}
void* CConnPool::createOneConn()
{
MYSQL* mysql;
mysql = mysql_init(0);
if(mysql == NULL)
{
cout << "mysql_init fail**" << endl;
return NULL;
}
if(mysql_real_connect(mysql, m_szMysqlIp , m_szUser , m_szPwd, m_szDbName , m_nMysqlPort, NULL,0)==NULL)
{
cout << "connect failure!" << endl;
return NULL;
}
else
{
cout << "connect success!" << endl;
}
//
return mysql;
}
int CConnPool::Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum)
{
strcpy(m_szMysqlIp, strMysqlIp.c_str());
strcpy( m_szUser, strUser.c_str());
strcpy(m_szPwd, strPwd.c_str());
strcpy(m_szDbName, strDbName.c_str());
m_nMysqlPort = nMysqlPort;
m_nConnNum = nConnNum;
MYSQL* mysql;
for(int i=0; i<nConnNum; i++)
{
mysql = (MYSQL*)this->createOneConn();
if(mysql == NULL)
return -1;
//
sConStatus* scs = new sConStatus();
scs->connAddr = mysql;
scs->useStatus = US_IDLE;
m_vectorConn.push_back(scs);
m_mapVI[scs] = i;
m_mapMysqlScs[mysql] = scs;
}
m_nConnNum = nConnNum;
}
//从连接池中取一个连接,同时,给它做一个标记,表明它已经被使用,防止别的线程再使用。
void* CConnPool::getOneConn()
{
int N = m_vectorConn.size();
for(int i=0; i< N; i++)
{
CGuard guard(m_sMutex);
sConStatus* scs = (sConStatus*)m_vectorConn[i];
if(scs->useStatus == US_IDLE)
{
scs->useStatus = US_USE;
return scs->connAddr;
}
}
//
return NULL;
}
//把连接归还给连接池。同时,给它做一个标记,表明它是空闲的,可以使用。
void CConnPool::retOneConn(void* pMysql)
{
if(!pMysql)
return;
//
map<void*, void*>::iterator it1;
map<void*, int>::iterator it2;
CGuard guard(m_sMutex);
it1 = m_mapMysqlScs.find(pMysql);
if(it1 == m_mapMysqlScs.end())
return;
it2 = m_mapVI.find(it1->second);
if(it2 == m_mapVI.end())
return;
int nInx = it2->second;
sConStatus* scs = (sConStatus*) m_vectorConn[nInx];
scs->useStatus = US_IDLE;
}
void CConnPool::checkConn()
{
map<void*, void*>::iterator it1;
MYSQL* mysql;
//
for(int i=0; i<m_nConnNum ; i++)
{
CGuard guard(m_sMutex);
sConStatus* scs = (sConStatus*)m_vectorConn[i];
if(scs->useStatus == US_USE)
continue;
//
mysql =(MYSQL*)(scs->connAddr);
int status=mysql_query(mysql, "select count(*) from t_user;" );
if(status != 0) //说明连接已经不可用了。
{
it1 = m_mapMysqlScs.find(mysql);
if(it1 != m_mapMysqlScs.end())
{
m_mapMysqlScs.erase(it1);
}
//
mysql_close(mysql);
//
mysql = (MYSQL*)this->createOneConn();
m_mapMysqlScs[mysql] = scs;
}
}
//
}
////////////////////////////// 2011-01-20, 这个类这样写,感觉耦合性更为松散,比较好。使用起来也好理解一些。
CConnPoolV2::CConnPoolV2( )
{
}
CConnPoolV2::~CConnPoolV2( )
{
}
//创建一个连接,并设为 IDLE状态。
void* CConnPoolV2::createOneConn()
{
try
{
CEncapMysql* pEM = new CEncapMysql();
if(pEM == NULL)
{
printf("pEM == NULL**\r\n");
return NULL;
}
//
int nRet = pEM->Connect(m_strMysqlIp.c_str(), m_strUser.c_str(), m_strPwd.c_str());
if(nRet != 0)
{
printf("pEM->Connect fail**\r\n");
return NULL;
}
//
pEM->SetIdle();
//
return pEM;
}
catch(...)
{
printf("createOneConn exception**\r\n");
return NULL;
}
}
//成功: 返回0
int CConnPoolV2::Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum)
{
m_strMysqlIp = strMysqlIp;
m_strUser = strUser;
m_strPwd = strPwd;
m_strDbName = strDbName;
m_nMysqlPort = nMysqlPort;
m_nConnNum = nConnNum;
CEncapMysql* pEM;
int nRet;
for(int i=0; i<nConnNum; i++)
{
pEM = (CEncapMysql*)this->createOneConn();
if(!pEM )
return -1;
//
m_vectorConn.push_back(pEM);
m_mapVI[pEM] = i;
}
return 0;
}
void* CConnPoolV2::getOneConn()
{
CGuard guard(m_sMutex);
//
for(int i=0; i< m_nConnNum; i++)
{
CEncapMysql* pEM = (CEncapMysql*)m_vectorConn[i];
if( pEM->IsIdle())
{
pEM->SetUsed();
return pEM;
}
}
//可能访问MYSQL的用户较多,连接池中已无空闲连接了。 只要总连接数没有超限,就新建一个连接。
if(m_nConnNum < MYSQL_CONN_NUM_MAX_VALUE)
{
CEncapMysql* pEM = (CEncapMysql*)this->createOneConn();
if(!pEM )
return NULL;
//
m_vectorConn.push_back(pEM);
m_mapVI[pEM] = m_nConnNum++;
}
//
return NULL;
}
void CConnPoolV2::retOneConn(void* pConn)
{
map<void*, int>::iterator it;
CGuard guard(m_sMutex);
it = m_mapVI.find(pConn);
if(it == m_mapVI.end())
{
printf("retOneConn fail***\n");
return;
}
int nInx = it->second;
CEncapMysql* pEM = (CEncapMysql*) m_vectorConn[nInx];
pEM->SetIdle();
printf("retOneConn succ!\n");
}
void CConnPoolV2::checkConn()
{
//暂时可以不实现。 因为查询失败时,已重新连接了。
}
原文链接:
http://blog.csdn.net/midle110/article/details/19564463
版本一:
连接池为了解决频繁的创建、销毁所带来的系统开销。
简而言之,就是 自己先创建一定量的连接,然后在需要的时候取出一条连接使用。
当然如果你只有一个线程连接数据库,而且不是实时返回结果,那么你完全不必用连接池。
想一下网络大型游戏服务器,你就明白为什么需要连接池了。
自己敲代码写了一个简单的类,实现连接池,虽然没有mysql++那么强大,但是还是自己有收获。
Csqlpool.h 头文件实现如下:
[cpp] view
plain copy
#pragma once
#include <WinSock2.h>
#include <mysql.h>
#include <list>
#pragma comment( lib , "libmysql.lib" )
using namespace std;
class Csqlpool
{
public:
~Csqlpool(void);
static Csqlpool *GetSqlPool();
bool IniSqlPool( const char *host , const char *name , const char *pwd , unsigned int port , unsigned int conMax ); //初始化连接池
bool SelectDB( MYSQL *sql, const char *DB); //选择数据库
MYSQL *GetConnect(); // 获取连接
void RelConnect(MYSQL *sql) ; // 释放连接
MYSQL_RES* GetQuery( MYSQL *sql , const char *query); //mysql操作 增删查改
void RelQuery(MYSQL_RES *res); //释放MYSQL_RES资源
bool Query(MYSQL *sql , const char *query); //增、删、改操作
protected:
Csqlpool(void);
private:
list<MYSQL *> m_sql_free; //空闲连接
static Csqlpool *pSqlPool;
CRITICAL_SECTION m_session; //获取空闲线程
};
Csqlpool.cpp 实现如下:
[cpp] view
plain copy
#include "StdAfx.h"
#include "Csqlpool.h"
Csqlpool *Csqlpool::pSqlPool = NULL;
Csqlpool::Csqlpool(void)
{
InitializeCriticalSection( &m_session );
}
Csqlpool::~Csqlpool(void)
{
while ( m_sql_free.size() )
{
mysql_close( m_sql_free.front() );
m_sql_free.pop_front();
}
DeleteCriticalSection(&m_session);
}
Csqlpool* Csqlpool::GetSqlPool()
{
if ( pSqlPool == NULL )
{
return new Csqlpool;
}
return pSqlPool;
}
bool Csqlpool::IniSqlPool( const char *host ,const char *name , const char *pwd , unsigned int port , unsigned int conMax ) //初始化连接池
{
int nsum = 0 ;
for (unsigned int i = 0 ; i < conMax ;++i )
{
MYSQL *pmysql;
pmysql = mysql_init( (MYSQL*)NULL );
if ( pmysql != NULL )
{
if ( mysql_real_connect( pmysql , host , name , pwd , NULL , 3306 , NULL , 0 ) )
{
m_sql_free.push_back(pmysql);
}
else
{
if ( nsum++ == 100 )
{
return false;
}
continue;
}
}
continue;
}
return true;
}
bool Csqlpool::SelectDB( MYSQL *sql, const char *DB) //选择数据库
{
if(mysql_select_db(sql , DB))
{
return false;
}
return true;
}
MYSQL* Csqlpool::GetConnect() // 获取连接
{
if ( m_sql_free.size() )
{
EnterCriticalSection(&m_session);
MYSQL *mysql = m_sql_free.front();
m_sql_free.pop_front();
LeaveCriticalSection(&m_session);
return mysql;
}
else
return NULL;
}
void Csqlpool::RelConnect(MYSQL *sql) // 释放连接
{
EnterCriticalSection(&m_session);
m_sql_free.push_back(sql);
LeaveCriticalSection(&m_session);
}
MYSQL_RES* Csqlpool::GetQuery( MYSQL *sql , const char *query) //查询操作
{
if ( mysql_query( sql , query ) == 0 )
{
return mysql_store_result( sql );
}
else
return NULL;
}
void Csqlpool::RelQuery(MYSQL_RES *res) //mysql_res release
{
mysql_free_result(res);
}
bool Csqlpool::Query(MYSQL *sql , const char *query) //增、删、改操作
{
if ( mysql_query( sql , query ) )
{
return false;
}
return true;
}
testsqlpool.cpp 测试文件实现如下:
[cpp] view
plain copy
// testsqlpool.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Csqlpool.h"
#include <iostream>
using namespace std;
Csqlpool *psql = Csqlpool::GetSqlPool();
DWORD WINAPI ThreadProc( LPVOID lpParameter);
int _tmain(int argc, _TCHAR* argv[])
{
if(!psql->IniSqlPool("127.0.0.1" , "root" ,"123",3306,10))
{
cout<<"连接错误"<<endl;
}
HANDLE phan[2] ;
DWORD threadid[2];
int n1 = 0, n2 = 100;;
phan[0] = CreateThread( NULL , 0 , ThreadProc , &n1 , 0 , &threadid[0] );
phan[1] = CreateThread( NULL , 0 , ThreadProc , &n2 , 0 , &threadid[1] );
WaitForMultipleObjects( 2 , phan , true , INFINITE );
CloseHandle(phan[0]);
CloseHandle(phan[1]);
return 0;
}
DWORD WINAPI ThreadProc( LPVOID lpParameter)
{
int index = *(int *)lpParameter ;
int i = 1;
MYSQL *sql = psql->GetConnect();
string stemp = "insert into actor( actor_id , first_name , last_name,last_update )values(\"";
string strsql;
char str[10];
if ( psql->SelectDB(sql , "sakila") )
{
while ( i != 100 )
{
sprintf( str , "%d" , i+index );
strsql = stemp ;
strsql += str;
strsql += "\",\"0\",\"0\",\"0\")";
if(!sql)
return 0;
if(!psql->Query( sql ,strsql.c_str() ))
{
cout<<"add false"<<endl;
}
++i;
}
psql->RelConnect(sql);
}
return 0;
}
版本二:
一、头文件【存为:connPool.h】
#ifndef __CONNECTION_POOL_H__
#define __CONNECTION_POOL_H__
#include "mutex.h"
#define MYSQL_CONN_NUM_MAX_VALUE 500
using namespace std;
enum _USE_STATUS
{
US_USE = 0,
US_IDLE = 1
};
typedef struct _sConStatus
{
void* connAddr;
int useStatus;
}sConStatus;
class CConnPool
{
public:
CConnPool();
~CConnPool();
public:
int Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum);//connection pool init
void* getOneConn();//get a connection
void retOneConn(void* pMysql);// return a connection
void checkConn(); // check the connection if is alive
void* createOneConn();
public:
char m_szMysqlIp[100];
char m_szUser[100];
char m_szPwd[100];
char m_szDbName[100];
int m_nMysqlPort;
int m_nConnNum;
public:
CMutex m_sMutex;
vector<void*> m_vectorConn;
map<void*, int> m_mapVI;
map<void*, void*> m_mapMysqlScs;
};
class CConnPoolV2
{
public:
CConnPoolV2();
~CConnPoolV2();
public:
int Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum);//connection pool init
void* getOneConn(); //从连接池取一个连接
void retOneConn(void* pConn);// 连接用完了,把它放回连接池。以便其他人用。
void checkConn(); // check the connection if is alive
void* createOneConn();
private:
string m_strMysqlIp;
string m_strUser;
string m_strPwd;
string m_strDbName;
int m_nMysqlPort;
int m_nConnNum;
private:
CMutex m_sMutex;
vector<void*> m_vectorConn;
map<void*, int> m_mapVI; // 从连接的地址,快速找到索引,便于存放到m_vectorConn中。
};
#endif
二、源码【存为:connPool.cpp】
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <time.h>
#include <iostream>
#include <memory>
#include <string>
#include <map>
#include <vector>
#include "mysql.h"
#include "encapsulation_mysql.h"
#include "connPool.h"
#include "mutex.h"
using namespace std;
using namespace EncapMysql;
CConnPool::CConnPool( )
{
}
CConnPool::~CConnPool( )
{
}
void* CConnPool::createOneConn()
{
MYSQL* mysql;
mysql = mysql_init(0);
if(mysql == NULL)
{
cout << "mysql_init fail**" << endl;
return NULL;
}
if(mysql_real_connect(mysql, m_szMysqlIp , m_szUser , m_szPwd, m_szDbName , m_nMysqlPort, NULL,0)==NULL)
{
cout << "connect failure!" << endl;
return NULL;
}
else
{
cout << "connect success!" << endl;
}
//
return mysql;
}
int CConnPool::Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum)
{
strcpy(m_szMysqlIp, strMysqlIp.c_str());
strcpy( m_szUser, strUser.c_str());
strcpy(m_szPwd, strPwd.c_str());
strcpy(m_szDbName, strDbName.c_str());
m_nMysqlPort = nMysqlPort;
m_nConnNum = nConnNum;
MYSQL* mysql;
for(int i=0; i<nConnNum; i++)
{
mysql = (MYSQL*)this->createOneConn();
if(mysql == NULL)
return -1;
//
sConStatus* scs = new sConStatus();
scs->connAddr = mysql;
scs->useStatus = US_IDLE;
m_vectorConn.push_back(scs);
m_mapVI[scs] = i;
m_mapMysqlScs[mysql] = scs;
}
m_nConnNum = nConnNum;
}
//从连接池中取一个连接,同时,给它做一个标记,表明它已经被使用,防止别的线程再使用。
void* CConnPool::getOneConn()
{
int N = m_vectorConn.size();
for(int i=0; i< N; i++)
{
CGuard guard(m_sMutex);
sConStatus* scs = (sConStatus*)m_vectorConn[i];
if(scs->useStatus == US_IDLE)
{
scs->useStatus = US_USE;
return scs->connAddr;
}
}
//
return NULL;
}
//把连接归还给连接池。同时,给它做一个标记,表明它是空闲的,可以使用。
void CConnPool::retOneConn(void* pMysql)
{
if(!pMysql)
return;
//
map<void*, void*>::iterator it1;
map<void*, int>::iterator it2;
CGuard guard(m_sMutex);
it1 = m_mapMysqlScs.find(pMysql);
if(it1 == m_mapMysqlScs.end())
return;
it2 = m_mapVI.find(it1->second);
if(it2 == m_mapVI.end())
return;
int nInx = it2->second;
sConStatus* scs = (sConStatus*) m_vectorConn[nInx];
scs->useStatus = US_IDLE;
}
void CConnPool::checkConn()
{
map<void*, void*>::iterator it1;
MYSQL* mysql;
//
for(int i=0; i<m_nConnNum ; i++)
{
CGuard guard(m_sMutex);
sConStatus* scs = (sConStatus*)m_vectorConn[i];
if(scs->useStatus == US_USE)
continue;
//
mysql =(MYSQL*)(scs->connAddr);
int status=mysql_query(mysql, "select count(*) from t_user;" );
if(status != 0) //说明连接已经不可用了。
{
it1 = m_mapMysqlScs.find(mysql);
if(it1 != m_mapMysqlScs.end())
{
m_mapMysqlScs.erase(it1);
}
//
mysql_close(mysql);
//
mysql = (MYSQL*)this->createOneConn();
m_mapMysqlScs[mysql] = scs;
}
}
//
}
////////////////////////////// 2011-01-20, 这个类这样写,感觉耦合性更为松散,比较好。使用起来也好理解一些。
CConnPoolV2::CConnPoolV2( )
{
}
CConnPoolV2::~CConnPoolV2( )
{
}
//创建一个连接,并设为 IDLE状态。
void* CConnPoolV2::createOneConn()
{
try
{
CEncapMysql* pEM = new CEncapMysql();
if(pEM == NULL)
{
printf("pEM == NULL**\r\n");
return NULL;
}
//
int nRet = pEM->Connect(m_strMysqlIp.c_str(), m_strUser.c_str(), m_strPwd.c_str());
if(nRet != 0)
{
printf("pEM->Connect fail**\r\n");
return NULL;
}
//
pEM->SetIdle();
//
return pEM;
}
catch(...)
{
printf("createOneConn exception**\r\n");
return NULL;
}
}
//成功: 返回0
int CConnPoolV2::Init(string& strMysqlIp, string& strUser, string& strPwd, string& strDbName, int nMysqlPort, int nConnNum)
{
m_strMysqlIp = strMysqlIp;
m_strUser = strUser;
m_strPwd = strPwd;
m_strDbName = strDbName;
m_nMysqlPort = nMysqlPort;
m_nConnNum = nConnNum;
CEncapMysql* pEM;
int nRet;
for(int i=0; i<nConnNum; i++)
{
pEM = (CEncapMysql*)this->createOneConn();
if(!pEM )
return -1;
//
m_vectorConn.push_back(pEM);
m_mapVI[pEM] = i;
}
return 0;
}
void* CConnPoolV2::getOneConn()
{
CGuard guard(m_sMutex);
//
for(int i=0; i< m_nConnNum; i++)
{
CEncapMysql* pEM = (CEncapMysql*)m_vectorConn[i];
if( pEM->IsIdle())
{
pEM->SetUsed();
return pEM;
}
}
//可能访问MYSQL的用户较多,连接池中已无空闲连接了。 只要总连接数没有超限,就新建一个连接。
if(m_nConnNum < MYSQL_CONN_NUM_MAX_VALUE)
{
CEncapMysql* pEM = (CEncapMysql*)this->createOneConn();
if(!pEM )
return NULL;
//
m_vectorConn.push_back(pEM);
m_mapVI[pEM] = m_nConnNum++;
}
//
return NULL;
}
void CConnPoolV2::retOneConn(void* pConn)
{
map<void*, int>::iterator it;
CGuard guard(m_sMutex);
it = m_mapVI.find(pConn);
if(it == m_mapVI.end())
{
printf("retOneConn fail***\n");
return;
}
int nInx = it->second;
CEncapMysql* pEM = (CEncapMysql*) m_vectorConn[nInx];
pEM->SetIdle();
printf("retOneConn succ!\n");
}
void CConnPoolV2::checkConn()
{
//暂时可以不实现。 因为查询失败时,已重新连接了。
}
相关文章推荐
- MySQL基础知识总结
- 看MySql如何实现批量操作
- MySQL Hash索引和B-Tree索引的区别
- 再谈Mysql中limit后的注入
- MySQL双主热备问题处理
- 使用Loadrunner11录制MySQL协议脚本
- 学习数据库之MySql数据库
- MySQL数据库总结(11)索引
- Mysql数据库常用分库和分表方式
- MySQL数据库总结(10)存储引擎与事务处理
- MySql语句大全:创建、授权、查询、修改等(转)
- MySQL数据库总结(9)触发器
- MySql之ALTER命令用法详细解读(转)
- 修改mysql root 密码 及 mysql 远程访问
- MySQL数据库总结(8)字符集与校对集
- MySQL数据库总结(7)视图
- MySQL数据库总结(6)列类型及列的增删改
- MySQL数据库总结(5)左连接,右连接,内连接
- MySQL数据库总结(4)子查询与联合
- Ubuntu15.10操作mysql5.6数据库