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);
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值