在LINUX下用C/C++写了一个连接池(访问MYSQL)的类
2012-02-25 17:32
405 查看
一、头文件【存为: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()
{
//暂时可以不实现。因为查询失败时,已重新连接了。
}
#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()
{
//暂时可以不实现。因为查询失败时,已重新连接了。
}
相关文章推荐
- Linux下C++访问MySQL 【转】
- Linux下C++访问MySQL
- Linux下C++访问MySQL
- 【数据库开发】如何创建MySQL数据库连接池(一个基于libmysql的MySQL数据库连接池示例(C/C++版))
- Linux下C++访问MySQL
- linux c++编写访问mysql程序,访问数据库出错,解决方法
- Linux下C++访问MySQL
- 在vc中通过连接池操作mysql(api方式),附c++访问mysql的封装类
- Linux下C++访问MySQL
- Linux平台下从零开始写一个C语言访问MySQL的测试程序
- linux下用codeblocks用C++访问mysql出现的问题!
- Linux下C++访问mysql出现函数undefined reference
- linux下c++访问mysql的编译问题
- Linux下C++访问MySQL
- Linux下C/C++编程访问MYSQL
- Linux下 C++ 访问 MySQL 数据库
- Linux下C++访问MySQL
- Linux下eclipse及mysql安装,c++访问mysql数据库
- Linux下C++访问MySQL