数据库模块的功能:验证客户端登录。
单例模式
与上一节的日志模块功能相同。
保证只能一个数据库对象
connection_pool* connection_pool::Getinstance()//
{
static connection_pool connpool;
return &connpool;
}
数据库连接池
1.使用链表实现,静态大小的连接容量。
2.数据库对象初始化连接池时,传入MYSQL初始化后的对象。
3.传入完成后要信号量的大小,大小为数据池的大小。
mysql=mysql_init(mysql);
mysql=mysql_real_connect(mysql,url.c_str(),user.c_str(),passwd.c_str(),databasename.c_str(),port,NULL,0);
connlist.push_back(mysql);
reserve=sem(m_freeconn);
++m_freeconn;
m_maxconn=m_freeconn;
1.获取MYSQL连接 使用互斥锁保证线程安全
MYSQL*connection_pool::Getconnection()
{
MYSQL*con=NULL;
if(0==connlist.size())
{
return NULL;
}
reserve.wait();//等待连接池的对象
lock.lock(); //存取时使用互斥锁
con=connlist.front();
connlist.pop_front();
--m_freeconn;
++m_curconn;
lock.unlock();
return con;
}
2.释放MYSQL连接,把连接放回连接池中
bool connection_pool::Releaseconnection(MYSQL*con)
{
if(!con)
{
return false;
}
lock.lock();
connlist.push_back(con);
--m_curconn;
++m_freeconn;
lock.unlock();
reserve.post(); //信号量加一
return true;
}
RAII
RAII,也称为“资源获取就是初始化”。它保证在任何情况下,使用对象时先构造对象,最后析构对象。
connectionRAII:: connectionRAII(MYSQL**SQL,connection_pool*connpool)
{
*SQL=connpool->Getconnection();//获取数据库对象
connRAII=*SQL; //初始化
poolRAII=connpool;//初始化
}
connectionRAII::~connectionRAII()
{
poolRAII->Releaseconnection(connRAII); //调用释放连接
}
总结:
1.使用互斥锁时,要留意死锁的发生。
2.信号量要与连接池数量同时更新。