这是我封装的mysql数据库连接池代码,在用于多线程执行时,会出现如下错误:
0x00a35a64 in free_root () from /usr/lib/mysql/libmysqlclient.so.14
(gdb) bt
#0 0x00a35a64 in free_root () from /usr/lib/mysql/libmysqlclient.so.14
#1 0x00a4ee81 in free_rows () from /usr/lib/mysql/libmysqlclient.so.14
#2 0x00a4f1e7 in mysql_free_result () from /usr/lib/mysql/libmysqlclient.so.14
#3 0x08060464 in ReleaseConn (id_conn=8, queryres=0xb7fe1ec8) at mysqlpool.cpp:367以上是错误信息,请大虾指点!源程序如下:struct everyConn *sparehead,*sparetail,*usehead,*usetail;函数功能: 向使用池添加一个连接
int AddNode(struct everyConn *node)
{
if(node == NULL)
{
return FAILURE;
}
usetail->next = node;
usetail = usetail->next;
return SUCCESS;
}
函数功能: 从空闲池取下一个连接
int DeleteNode(struct everyConn *&Node)
{
if(sparehead->next == NULL)
{
printf("sparepool is empty\n");
return FAILURE;
}
Node = sparehead->next;
sparehead->next = Node->next;
Node->next = NULL;
return SUCCESS;
}
函数功能: 连接mysql数据库
int MysqlConnect(MYSQL *mysql,char *host,char *user,char *passwd,char *database)
{
mysql_init(mysql);
if(mysql == NULL)
{
printf("mysql_init failed.");
return FAILURE;
}
if(mysql_real_connect(mysql,host,user,passwd,database,0,NULL,0) == NULL)
{
mysql_error(mysql);
return FAILURE;
}
return SUCCESS;
} 函数功能: 读取配置文件,得到初始连接个数
int GetConfig(char *filename)
{
FILE *fp;
int initcounts;
char str[strlength]={},*ch;
if((fp=fopen(filename,"rb"))==NULL)
{
printf("can not open this file.\n");
exit(0);
}
fgets(str,conflength,fp);
ch=str;
if(str==NULL)
return -1;
while((*ch)!='=')
ch++;
ch++;
initcounts=atoi(ch);
fclose(fp);
return(initcounts);
}
函数功能: 初始化连接池
void ConnPoolInit(char *host,char *user,char *passwd,char *database)
{
struct everyConn *temp;
int i,initConns;
initConns = GetConfig("mysql.config");
sparehead = (struct everyConn *)malloc(sizeof(struct everyConn));
sparehead->id = 0;
sparehead->flag = 0;
sparehead->useTimes = 0 ;
MysqlConnect(&(sparehead->conn),host,user,passwd,database);
sparehead->begin_time = time(NULL);
sparehead->next = NULL;
sparetail = sparehead;
for(i=0;i<initConns;i++)
{
temp = (struct everyConn *)malloc(sizeof(struct everyConn));
temp->id = i+1;
temp->flag = 0;
temp->useTimes = 0;
MysqlConnect(&(temp->conn),host,user,passwd,database);
temp->begin_time = time(NULL);
temp->next = NULL;
sparetail->next = temp;
sparetail = sparetail->next;
}
usehead = (struct everyConn*)malloc(sizeof(struct everyConn));
memset(usehead,0,sizeof(usehead));
usetail = usehead;
}
函数功能: 从连接池获得一个连接
int GetConn(int &connid)
{
pthread_mutex_t connidmutex;
struct everyConn *temp ;
int UseConnNum;
pthread_mutex_init(&connidmutex,NULL);
pthread_mutex_lock(&connidmutex);
if(sparehead->next == NULL)
{
UseConnNum = 0;
temp = usehead->next;
while(temp != NULL)
{
UseConnNum ++;
temp = temp->next;
}
if(UseConnNum > MAXCONNNUM)
{
printf("Have reached max value, please wait and try again......\n");
return FAILURE;
}
if(CreateNewConn(UseConnNum + 1) == -1)
{
printf("create new node failed\n");
return FAILURE;
}
connid = UseConnNum + 1;
pthread_mutex_unlock(&connidmutex);
return SUCCESS;
}
if(DeleteNode(temp) == -1)
{
return FAILURE;
}
temp->flag = 1;
if(AddNode(temp) == -1)
{
return FAILURE;
}
connid = temp->id;
pthread_mutex_unlock(&connidmutex);
return SUCCESS;
}函数功能: 检查连接
int CheckConn(int id_conn)
{
struct everyConn *temp;
temp = usehead->next;
while((temp->id != id_conn)&&(temp->next != NULL))
{
temp=temp->next;
}
if((temp->id == id_conn)&&(temp->flag == 1))
{
return SUCCESS;
}
return FAILURE;
}
函数功能: 执行没有返回结果的查询语句
** 入口参数:id_conn连接号,SQLstring无返回结果的查询语句,
** nSQLLen查询语句长度
** 出口参数:无
** 函数描述:成功返回0,失败返回-1
**
函数功能: 执行有返回结果的查询语句
int ExcuteQuery(int id_conn,char * SQLstring,int nSQLLen,MYSQL_RES *&res)
{
struct everyConn *mysqlSQL;
int state;
if(usehead->next == NULL)
{
return FAILURE;
}
mysqlSQL=usehead->next;
while((mysqlSQL->id != id_conn)&&(mysqlSQL->next != NULL))
{
mysqlSQL=mysqlSQL->next;
}
if(mysqlSQL->id != id_conn)
{
return FAILURE;
}
mysqlSQL->useTimes ++;
state = mysql_real_query(&(mysqlSQL->conn),SQLstring,nSQLLen);
if(state != 0)
{
mysql_errno(&(mysqlSQL->conn));
return FAILURE;
}
res = mysql_store_result(&(mysqlSQL->conn));
return SUCCESS;
}
函数功能: 释放连接
int ReleaseConn(int id_conn, MYSQL_RES *queryres)
{
struct everyConn *temp,*follow;
if(queryres != NULL)
{
mysql_free_result(queryres);
}
temp = usehead->next;
while((temp->id != id_conn)&&(temp->next != NULL))
{
follow = temp;
temp = temp->next;
}
if(temp->id != id_conn)
{
return FAILURE;
}
if(temp == usehead->next)
{
if(usehead->next == usetail)
{
usetail = usehead;
usehead->next = NULL;
}
else
{
usehead->next = temp->next;
}
}
else
{
if(temp == usetail)
{
usetail = follow;
usetail->next = NULL;
}
else
{
follow->next = temp->next;
}
}
if(temp->useTimes >= maxUsetimes)
{
mysql_close(&(temp->conn));
MysqlConnect(&(temp->conn),"localhost","root","","AntiSpam_Gateway_db");
temp->begin_time = time(NULL);
temp->useTimes = 0;
}
temp->flag = 0;
temp->begin_time = time(NULL);
temp->next = NULL;
sparetail->next = temp;
sparetail = sparetail->next;
return SUCCESS;
}
函数功能: 建立新连接
int CreateNewConn(int connid)
{
struct everyConn *newnode;
newnode = (struct everyConn *)malloc(sizeof(struct everyConn));
newnode->id = connid;
newnode->flag = 1;
newnode->useTimes = 0;
MysqlConnect(&(newnode->conn),"localhost","root","","Junkmail_db");
newnode->begin_time = time(NULL);
newnode->next = NULL;
if(AddNode(newnode) == -1)
{
return FAILURE;
}
return SUCCESS;
}函数功能: 关闭连接池
void ClosePool()
{
struct everyConn *temp;
struct everyConn *follow;
free(usehead);
temp = sparehead;
while(temp != NULL)
{
mysql_close(&(temp->conn));
follow = temp;
temp = follow->next;
free(follow);
}
}
0x00a35a64 in free_root () from /usr/lib/mysql/libmysqlclient.so.14
(gdb) bt
#0 0x00a35a64 in free_root () from /usr/lib/mysql/libmysqlclient.so.14
#1 0x00a4ee81 in free_rows () from /usr/lib/mysql/libmysqlclient.so.14
#2 0x00a4f1e7 in mysql_free_result () from /usr/lib/mysql/libmysqlclient.so.14
#3 0x08060464 in ReleaseConn (id_conn=8, queryres=0xb7fe1ec8) at mysqlpool.cpp:367以上是错误信息,请大虾指点!源程序如下:struct everyConn *sparehead,*sparetail,*usehead,*usetail;函数功能: 向使用池添加一个连接
int AddNode(struct everyConn *node)
{
if(node == NULL)
{
return FAILURE;
}
usetail->next = node;
usetail = usetail->next;
return SUCCESS;
}
函数功能: 从空闲池取下一个连接
int DeleteNode(struct everyConn *&Node)
{
if(sparehead->next == NULL)
{
printf("sparepool is empty\n");
return FAILURE;
}
Node = sparehead->next;
sparehead->next = Node->next;
Node->next = NULL;
return SUCCESS;
}
函数功能: 连接mysql数据库
int MysqlConnect(MYSQL *mysql,char *host,char *user,char *passwd,char *database)
{
mysql_init(mysql);
if(mysql == NULL)
{
printf("mysql_init failed.");
return FAILURE;
}
if(mysql_real_connect(mysql,host,user,passwd,database,0,NULL,0) == NULL)
{
mysql_error(mysql);
return FAILURE;
}
return SUCCESS;
} 函数功能: 读取配置文件,得到初始连接个数
int GetConfig(char *filename)
{
FILE *fp;
int initcounts;
char str[strlength]={},*ch;
if((fp=fopen(filename,"rb"))==NULL)
{
printf("can not open this file.\n");
exit(0);
}
fgets(str,conflength,fp);
ch=str;
if(str==NULL)
return -1;
while((*ch)!='=')
ch++;
ch++;
initcounts=atoi(ch);
fclose(fp);
return(initcounts);
}
函数功能: 初始化连接池
void ConnPoolInit(char *host,char *user,char *passwd,char *database)
{
struct everyConn *temp;
int i,initConns;
initConns = GetConfig("mysql.config");
sparehead = (struct everyConn *)malloc(sizeof(struct everyConn));
sparehead->id = 0;
sparehead->flag = 0;
sparehead->useTimes = 0 ;
MysqlConnect(&(sparehead->conn),host,user,passwd,database);
sparehead->begin_time = time(NULL);
sparehead->next = NULL;
sparetail = sparehead;
for(i=0;i<initConns;i++)
{
temp = (struct everyConn *)malloc(sizeof(struct everyConn));
temp->id = i+1;
temp->flag = 0;
temp->useTimes = 0;
MysqlConnect(&(temp->conn),host,user,passwd,database);
temp->begin_time = time(NULL);
temp->next = NULL;
sparetail->next = temp;
sparetail = sparetail->next;
}
usehead = (struct everyConn*)malloc(sizeof(struct everyConn));
memset(usehead,0,sizeof(usehead));
usetail = usehead;
}
函数功能: 从连接池获得一个连接
int GetConn(int &connid)
{
pthread_mutex_t connidmutex;
struct everyConn *temp ;
int UseConnNum;
pthread_mutex_init(&connidmutex,NULL);
pthread_mutex_lock(&connidmutex);
if(sparehead->next == NULL)
{
UseConnNum = 0;
temp = usehead->next;
while(temp != NULL)
{
UseConnNum ++;
temp = temp->next;
}
if(UseConnNum > MAXCONNNUM)
{
printf("Have reached max value, please wait and try again......\n");
return FAILURE;
}
if(CreateNewConn(UseConnNum + 1) == -1)
{
printf("create new node failed\n");
return FAILURE;
}
connid = UseConnNum + 1;
pthread_mutex_unlock(&connidmutex);
return SUCCESS;
}
if(DeleteNode(temp) == -1)
{
return FAILURE;
}
temp->flag = 1;
if(AddNode(temp) == -1)
{
return FAILURE;
}
connid = temp->id;
pthread_mutex_unlock(&connidmutex);
return SUCCESS;
}函数功能: 检查连接
int CheckConn(int id_conn)
{
struct everyConn *temp;
temp = usehead->next;
while((temp->id != id_conn)&&(temp->next != NULL))
{
temp=temp->next;
}
if((temp->id == id_conn)&&(temp->flag == 1))
{
return SUCCESS;
}
return FAILURE;
}
函数功能: 执行没有返回结果的查询语句
** 入口参数:id_conn连接号,SQLstring无返回结果的查询语句,
** nSQLLen查询语句长度
** 出口参数:无
** 函数描述:成功返回0,失败返回-1
**
函数功能: 执行有返回结果的查询语句
int ExcuteQuery(int id_conn,char * SQLstring,int nSQLLen,MYSQL_RES *&res)
{
struct everyConn *mysqlSQL;
int state;
if(usehead->next == NULL)
{
return FAILURE;
}
mysqlSQL=usehead->next;
while((mysqlSQL->id != id_conn)&&(mysqlSQL->next != NULL))
{
mysqlSQL=mysqlSQL->next;
}
if(mysqlSQL->id != id_conn)
{
return FAILURE;
}
mysqlSQL->useTimes ++;
state = mysql_real_query(&(mysqlSQL->conn),SQLstring,nSQLLen);
if(state != 0)
{
mysql_errno(&(mysqlSQL->conn));
return FAILURE;
}
res = mysql_store_result(&(mysqlSQL->conn));
return SUCCESS;
}
函数功能: 释放连接
int ReleaseConn(int id_conn, MYSQL_RES *queryres)
{
struct everyConn *temp,*follow;
if(queryres != NULL)
{
mysql_free_result(queryres);
}
temp = usehead->next;
while((temp->id != id_conn)&&(temp->next != NULL))
{
follow = temp;
temp = temp->next;
}
if(temp->id != id_conn)
{
return FAILURE;
}
if(temp == usehead->next)
{
if(usehead->next == usetail)
{
usetail = usehead;
usehead->next = NULL;
}
else
{
usehead->next = temp->next;
}
}
else
{
if(temp == usetail)
{
usetail = follow;
usetail->next = NULL;
}
else
{
follow->next = temp->next;
}
}
if(temp->useTimes >= maxUsetimes)
{
mysql_close(&(temp->conn));
MysqlConnect(&(temp->conn),"localhost","root","","AntiSpam_Gateway_db");
temp->begin_time = time(NULL);
temp->useTimes = 0;
}
temp->flag = 0;
temp->begin_time = time(NULL);
temp->next = NULL;
sparetail->next = temp;
sparetail = sparetail->next;
return SUCCESS;
}
函数功能: 建立新连接
int CreateNewConn(int connid)
{
struct everyConn *newnode;
newnode = (struct everyConn *)malloc(sizeof(struct everyConn));
newnode->id = connid;
newnode->flag = 1;
newnode->useTimes = 0;
MysqlConnect(&(newnode->conn),"localhost","root","","Junkmail_db");
newnode->begin_time = time(NULL);
newnode->next = NULL;
if(AddNode(newnode) == -1)
{
return FAILURE;
}
return SUCCESS;
}函数功能: 关闭连接池
void ClosePool()
{
struct everyConn *temp;
struct everyConn *follow;
free(usehead);
temp = sparehead;
while(temp != NULL)
{
mysql_close(&(temp->conn));
follow = temp;
temp = follow->next;
free(follow);
}
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货