CYYMysql 源码解读 3
Mysqlyy.cpp文件主要实现 mysql数据库连接池。
自己实现了mysql连接池之后,发现连接池就那么回事。系统一开始就申请一大堆东西在那里放着,等着你来用,省的你需要的时候申请,使用完之后又要释放的麻烦。
这里面没有使用内存池,如果一个服务器不是用内存池跑几个月是不是极限了?记得我大二的时候写屏幕实时显示的程序,没用内存池,跑了半个小时就挂掉了。
当然现在有了tcmalloc这等高富帅的神器,程序肯定会瞬间高档一个档次。
下面是Mysqlyy.cpp文件加我的注释
#include "StdAfx.h" #include ".\mysqlyy.h" #include "..\unicode.h" #include "../../include/zdebug.h" #include "H:\SYMobilePalaza\trunk\src\Core\NetCore_DLL\libiconvDLL\src\convert.h" //stl find #include <algorithm> CYYMysql::CYYMysql(void) { } CYYMysql::~CYYMysql(void) { } bool CYYMysql::Initialize(const char* Hostname, unsigned int port,const char* Username, const char* Password, const char* DatabaseName,int ConnectionCount,int JobCount) //初始化mysql连接池 { //////////////////////////////////////////////////////////////////////////// if (1) { char *tmp = "斗地主1"; char out[64]={‘\0‘}; if (CLibiconv::code_convert("gbk","utf-8",tmp,strlen(tmp)*2+1,out,64)>=0) { printf("test=%s\n",out); //Debug("%s",out); } else { printf("1 conver err\n"); } char out2[64]={‘\0‘}; if (CLibiconv::code_convert("utf-8","gbk",out,strlen(out),out2,64)>=0) { printf("test=%s\n",out2); //Debug("%s",out2); } else { printf("2 conver err\n"); } //return true; } //////////////////////////////////////////////////////////////////////////// my_bool my_true = true; for (int i=0;i<ConnectionCount;i++) { CYYMySqlCon *temp = new CYYMySqlCon; temp->_sql = mysql_init(NULL); if (!temp->_sql) { continue; } if(!mysql_real_connect(temp->_sql,Hostname,Username,Password,DatabaseName,port,NULL,0)) { printf("数据库连接失败,原因如下: %s\n",mysql_error(temp->_sql)); return false; } if (!temp->_sql) { //err mysql_close(temp->_sql); delete temp; temp = NULL; return false; } if(mysql_set_character_set(temp->_sql,"latin1"))//utf8,GBK { printf("字符集设置失败\n"); return false; } m_FreeList.push_back(temp); } for (int i=0;i<JobCount;i++) { CYYJob * job = new CYYJob; m_FreeJobList.push_back(job); } return true; } CYYMySqlCon * CYYMysql::GetFreeCon() //获取空闲连接 { CAutoLock lock(&m_SqlPoolLock); if (!m_FreeList.empty()) { CYYMySqlCon * temp = m_FreeList.front(); m_BusyList.push_back(temp); m_FreeList.pop_front(); return temp; } return NULL; } void CYYMysql::ReleaseCon(CYYMySqlCon*con) //释放已经使用过的连接 { //我觉得只需要维持一个free list就行了,程序结束的时候只需要释放free list CAutoLock lock(&m_SqlPoolLock); if (!con) { //err return; } m_FreeList.push_back(con); YYMySqlConListIt iter = find(m_BusyList.begin(),m_BusyList.end(),con); if (iter!=m_BusyList.end()) { m_BusyList.erase(iter); } else { //err } } CYYJob * CYYMysql::GetFreeJob(char *query) { CAutoLock lock(&m_jobPoolLock); CYYJob * job = NULL; if (m_FreeJobList.empty()) { job = new CYYJob; job->_con = GetFreeCon(); //当请求很多的时候 超过了mysql连接的最大数,这不是就失败了吗? //为什么不使用一个线程使用一个固定的mysql连接? if (!job->_con) { return NULL; } sprintf(job->_query,query); m_BusyJobList.push_back(job); return job; } else { job = m_FreeJobList.front(); job->_con = GetFreeCon(); sprintf(job->_query,query); m_BusyJobList.push_back(job); m_FreeJobList.pop_front(); return job; } return NULL; } void CYYMysql::ReleaseJob(CYYJob*job) { CAutoLock lock(&m_jobPoolLock); if (!job) { //err return; } m_FreeJobList.push_back(job); YYJobListIt iter = find(m_BusyJobList.begin(),m_BusyJobList.end(),job); if (iter!=m_BusyJobList.end()) { m_BusyJobList.erase(iter); } else { //err } } void CYYMysql::Start() { SYSTEM_INFO si; GetSystemInfo(&si); int processNum = si.dwNumberOfProcessors; //获取cpu核数 processNum = (processNum == 1) ? 2:processNum; m_ThreadPool.Start(processNum,processNum + 1); //启动线程池 ,但是网上的经验规则iocp线程数在2n+2比较好 } void CYYMysql::Stop() { m_ThreadPool.Stop(); } void CYYMysql::ExecuteQueryNoRet(char *query) { static CYYWorker * worker = new CYYWorker(this); CYYJob * job = GetFreeJob(query); m_ThreadPool.ProcessJob(job,worker); } bool CYYMysql::SelectDB(CYYMySqlCon*con,char *db) //选择数据库 { if (con && con->_sql) { if(mysql_select_db(con->_sql,db)==0) { return true; } } return false; } bool CYYMysql::Query(CYYMySqlCon*con,char*cmd,MYSQL_RES *res) //查询请求 { if (con && con->_sql) { if (mysql_real_query(con->_sql,cmd,strlen(cmd))==0) { if(mysql_field_count(con->_sql) > 0) { res = mysql_store_result(con->_sql); if (res) { return true; } } } } return false; } bool CYYMysql::Query(char*cmd,MySqlResultList *data) //增删改请求 { CYYMySqlCon*con = GetFreeCon(); //con没有回收 MYSQL_RES * res = NULL; if (con && con->_sql) { if (mysql_real_query(con->_sql,cmd,strlen(cmd))==0) { if(mysql_field_count(con->_sql) > 0) { res = mysql_store_result(con->_sql); if (res) { int rows = mysql_num_rows(res); int fields = mysql_num_fields(res); MYSQL_FIELD * fd; char keyName[32][32]={‘\0‘}; for(int i=0;fd = mysql_fetch_field(res);i++) { strcpy(keyName[i],fd->name); } for (int i=0;i<rows;i++) //结果存储 { MYSQL_ROW row = mysql_fetch_row(res); unsigned long *lengths = mysql_fetch_lengths(res); for (int j=0;j<fields;j++) { CMySqlResult tmp; memcpy(tmp._name,keyName[j],strlen(keyName[j])*2+1); memcpy(tmp._data,row[j],strlen(row[j])*2+1); tmp._fields = j; data->push_back(tmp); } } mysql_free_result(res);//结果集释放 return true; } } } } return false; } bool CYYMysql::GetFirstRow(CYYMySqlCon*con,char*cmd,MYSQL_ROW &row) { MYSQL_RES *res; if (Query(con,cmd,res)==true) { row = mysql_fetch_row(res); if (row) { return true; } } return false; } ////////////////////////////////////////////////////////////////////////// void CYYWorker::ProcessJob(IJobDesc* pJob) { CYYJob * job = (CYYJob*)pJob; MYSQL_RES res; this->_mysql->Query(job->_con,job->_query,&res); }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。