dbpool mysql_数据库连接池DBPool分析(四):mysql连接池 mysql_connection_pool

这个class的设计和MysqlObj不一样了,不会像MysqlObj提供Connect函数来进行连接,这里我直接就在构造函数当中创建好池,因为如果再提供一个init之类的函数来创建池的话我觉得与这个class的设计语意违背,毕竟池创建好就能直接使用了。

在构造函数当中使用到了boost的property_tree,目的就是从config里面读取database.xml或者database.json配置文件,从配置文件当中获取到host,user,dbname等等。

做的工作只有一件事情,从配置文件当中读取出的max_connections,说明了池的容量,需要建立这么多的连接数目,然后使用map来保存这个连接,map的first是连接指针,second指的是Mysql连接是否可用,true为可用,false为已经被其他的占用了。

析构函数的话直接轮询map,然后删除掉对应的指针,我现在正在想用shared_ptr来代替掉指针。

getConnection()函数就是说从池当中取出一个连接,就是轮询map,然后查找有用的连接。

这里为了应对多线程使用了锁,使用并非简单的mutex.lock()和mutex.unlock()。我更加喜欢使用RAII方式的unique_lock和lock_guard,但是unique_lock提供了更好的上锁和解锁机制。

releaseConnection()正好和getConnection()是相反的,也是用了unique_lock机制。

#include

#include

#include

#include "mysql_obj.h"

using std::string;

using std::vector;

using std::mutex;

using std::unique_lock;

using std::map;

using std::make_pair;

// 这个pool只做了一件事情,那就是创建poolsize个的连接,Mysql的最大连接数目是151

class MysqlPool

{

public:

// 批量创建连接在构造函数当中进行

MysqlPool();

// 析构函数就是顺序销毁MysqlObj指针

// 最后清空map

virtual ~MysqlPool();

// 从map当中选取一个连接

MysqlObj* getConnection();

// 释放特定的连接就是把map当中的bool值置为false

int releaseConnection(MysqlObj*);

// 构造函数创建poolsize个连接错误时候用来打印错误信息

string ErrorMessage() const;

private:

mutex resource_mutex;

public:

// 之所以要把这里设置成为public,是因为使用insert的方式来插入连接和是否可用的pair

// bool值为false的时候说明mysql连接被占用

map mysql_map;

private:

string host_ ;

string user_ ;

string password_ ;

string dbname_;

unsigned port_;

//Mysql的最大连接数为151,从database.xml或者database.json当中读取max_connections

int poolSize_;

//错误信息

string m_strErrorMessage;

};

#include "../include/mysql_connection_pool.h"

#include

#include

#include

#include

#include

#include

#include

#include

#include

using std::cout;

using std::endl;

MysqlPool::MysqlPool()

{

// 从配置文件database.xml当中读入mysql的ip, 用户, 密码, 数据库名称,

boost::property_tree::ptree pt;

const char* xml_path = "../config/database.xml";

boost::property_tree::read_xml(xml_path, pt);

//这段注释的代码是读取json配置文件的

// const char* json_path = "../config/database.json";

// boost::property_tree::read_json(json_path, pt);

BOOST_AUTO(child, pt.get_child("Config.MysqlConnection"));

for(BOOST_AUTO(pos, child.begin()); pos!= child.end(); ++pos)

{

if(pos->first == "IP")

host_ = pos->second.data();

if(pos->first == "Port")

port_ = boost::lexical_cast(pos->second.data());

if(pos->first == "User")

user_ = pos->second.data();

if(pos->first == "Passwd")

password_ = pos->second.data();

if(pos->first == "DBName")

dbname_ = pos->second.data();

if(pos->first == "max_connections")

poolSize_ = boost::lexical_cast(pos->second.data());

}

// 构造函数的作用就是根据poolSize的大小来构造多个映射

// 每个映射的连接都是同样的host,user,pass,dbname

for(int i=0; i

{

// boost::shared_ptr conn =

MysqlObj* conn = new MysqlObj(host_, user_, password_, dbname_, port_);

conn->Connect();

if(conn->Connect())

mysql_map.insert(make_pair(conn, 1));

else

{

m_strErrorMessage = conn->ErrorMessage();

delete conn;

}

}

}

MysqlPool::~MysqlPool()

{

// 析构函数就是顺序销毁MysqlObj指针

for(auto it = mysql_map.begin(); it != mysql_map.end(); ++it)

{

delete it->first;

}

mysql_map.clear();

}

// 从map当中得到一个连接

MysqlObj* MysqlPool::getConnection()

{

//get connection operation

MysqlObj* ret = NULL;

while(true)

{

bool flag = false;

for(auto it = mysql_map.begin(); it != mysql_map.end(); ++it)

{

unique_lock lk(resource_mutex);

if(it->second == true)

{

it->second = false;

ret = it->first;

flag = true;

break;

}

}

if(flag == true)

{

break;

}

else

{

usleep(1000);

continue;

}

}

return ret;

}

// 释放一个连接还给线程池

int MysqlPool::releaseConnection(MysqlObj* conn)

{

for(auto it = mysql_map.begin(); it != mysql_map.end(); ++it)

{

unique_lock lk(resource_mutex);

if(it->first == conn)

{

it->second = true;

break;

}

}

return 1;

}

string MysqlPool::ErrorMessage() const

{

return m_strErrorMessage;

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值