mysql init线程安全_mysql_init()线程安全问题

写了个C++的多线程压力测试工具,写了个压测mysql的例子,调用mysql就使用myqsl的c api,

调用mysql的业务代码如下:(都是在线程内部)

void init(){

//pthread_mutex_lock(&work_mutex);

my_connection=mysql_init(NULL);

if(mysql_real_connect(my_connection,"10.1.147.9","wangzytest","a1234561","wangzy",8066,NULL,0)){

printf("connection successfule \n");

}else{

fprintf(stderr,"connection failed\n");

if(mysql_errno(my_connection)){

fprintf(stderr,"%d,%sn",mysql_errno(my_connection),mysql_error(my_connection));

exit(0);

}

}

//pthread_mutex_unlock(&work_mutex);

}

int mysql_execute(Result *rs){

if(mysql_query(my_connection,"select * from users")){

rs->result=false;

rs->msg = string(mysql_error(my_connection));

return 0;

}else{

//suppose in the perf test ,wo don't case the mysql query value only care if the query is successfule;

//so here i just free the query result

mysql_result = mysql_store_result(my_connection);

rs->result=true;

rs->msg="ok";

mysql_free_result(mysql_result);

return 1;

}

}

void del(){

mysql_close(my_connection);

}

先调用一次init()

然后循环调用mysql_execute(),主线程来控制退出时间

最后执行完的时候,再调用一次del()函数

实际执行的时候,在虚拟机上执行1000个并发都没有问题,但是一旦将bin文件拷贝到物理机上执行,在10个线程以下,怎么执行都不会出错,但是线程数大于20个的时候,就会有很大的概率出现sigmentfault

仔细看了下代码实在是看不出哪里有问题,因为本地虚拟机1000个线程跑了20多次,一次都没出现问题. 没办法,只好用coredump来看下问题

查看堆栈

(gdb) where

#0  0x00007fce34f54bf9 in ?? () from /usr/lib64/libmysqlclient.so.16

#1  0x00007fce34f54f23 in ?? () from /usr/lib64/libmysqlclient.so.16

#2  0x00007fce34f5512f in get_charset_by_csname () from /usr/lib64/libmysqlclient.so.16

#3  0x00007fce34f7836a in mysql_init_character_set () from /usr/lib64/libmysqlclient.so.16

#4  0x00007fce34f79b9e in mysql_real_connect () from /usr/lib64/libmysqlclient.so.16

#5  0x0000000000405109 in MultiThread::init (this=0x7fce2800ed30) at run.cpp:130

#6  0x0000000000406af5 in MultiThread::run (this=0x7fce2800ed30) at run.cpp:55

#7  0x0000000000403cef in Thread::run1 (this=0x7fce2800ed30) at ../../include/Thread.h:61

#8  0x0000000000403d2d in Thread::run0 (pVoid=0x7fce2800ed30) at ../../include/Thread.h:45

#9  0x000000304ce064a7 in start_thread () from /lib64/libpthread.so.0

#10 0x000000304c6d3c2d in clone () from /lib64/libc.so.6

可以看到,是在mysql_real_connect() 的时候出错了,最后一个调用函数是get_charset_by_csname () ,也没有其他的信息,可以确定不是自己代码的问题

所以怀疑mysql 的cpi在连接阶段是存在线程不安全的

最后查出来是mysql_init(NULL); 是线程不安全的,在本地线程的相关数据的初始化的时候,会出现问题

简单的解决办法:

在mysql_real_connect()阶段加锁,因为这个是每个线程初始化的时候,只做一次的操作,因此也不会有什么性能损耗,添加了红色代码,再次测试就没有什么问题了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值