C MySql封装类 高性能连接池_在LINUX下用C/C++写了一个连接池(访问MYSQL)的类

一、头文件【存为: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 m_vectorConn;

map m_mapVI;

map

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 m_vectorConn;

map m_mapVI;

// 从连接的地址,快速找到索引,便于存放到m_vectorConn中。

};

#endif

二、源码【存为:connPool.cpp】

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 #include

 #include

#include

#include

#include

#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

{

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*>::iterator it1;

map

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*>::iterator it1;

MYSQL* mysql;

// for(int i=0;

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

{

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

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()

{

//暂时可以不实现。

因为查询失败时,已重新连接了。

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值