mysql的多线程安全问题:在mysql_real_connect时出现段错误。

 

  • 问题简化重现
19 #include
20 #include 21
22 void* func(void* arg)
23 {
24 MYSQL* mysql = (MYSQL *)arg;
26 mysql_real_connect(mysql, “127.0.0.1″, “root”, “213456″, “FC_word”, 3344, NULL, 0);
27 mysql_close(mysql);
29 return (void *)0;
30 }
31
32 int main()
33 {
34 MYSQL mysql;
35 if (NULL == mysql_init(&mysql)){
36 return -1;
37 }
38 pthread_t thread;
39 pthread_create(&thread, NULL, func, &mysql);
40 pthread_join(thread, NULL);
41
42 return 0;
43 }

会core掉:

#0 0×0000000000417db2 in my_stat ()
(gdb) bt
#0 0×0000000000417db2 in my_stat ()
#1 0×00000000004169f4 in my_read_charset_file ()
#2 0×0000000000416cb2 in init_available_charsets ()
#3 0×00000000004170ea in get_charset_by_csname ()
#4 0×0000000000405fda in mysql_init_character_set ()
#5 0×0000000000407024 in mysql_real_connect ()

 

  • 问题原因

粗略看了下源代码,Mysql_init()会初始化一些线程私有数据。 Mysql_init()中调用my_thread_init(), 其中设置线程私有数据。

  • 解决办法

所以可以这么使用:(1)mysql_init()和mysql_real_connect()放在一起:
(2)调用mysql_thread_init()和mysql_thread_end()来初始化和线程相关的数据
如:

22 void* func(void* arg)
23 {
24 MYSQL* mysql = (MYSQL *)arg;
25 mysql_thread_init();
26 mysql_real_connect(mysql, “127.0.0.1″, “root”, “213456″, “FC_word”, 3344, NULL, 0);
27 mysql_close(mysql);
28 mysql_thread_end();
29 return (void *)0;
30 }

 

  • 其他

另外还遇到一个比较诡异的问题,MYSQL_OPT_RECONNECT不起作用。具体情况是:
Mysql server 使用5.0.22版本, mysql client api 使用third-64/mysql下的5.1.30版本, 重连不起作用,mysql_error也被置空
Mysql server 使用5.0.45版本(凤巢线上版本), mysql client api 使用third-64/mysql下的5.1.30版本, 重连起作用了。
提醒大家使用时注意mysql sever 和client api的版本,^_^

  • 其他共享经验

mysql_init()不是完全线程安全的,但是只要成功调用一次就后就线程安全了,如果有多线程并发使用mysql_init(),建议在程序初始化时空调一次mysql_init(),他的这点特性很像qsort() 。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值