mysql Connector C/C++ 多线程封装
2015-12-06 22:30
246 查看
http://www.cnblogs.com/dangerman/archive/2013/01/17/2864694.html
mysql Connector C/C++ 多线程封装
在网上找了好久,有很多封装,但是感觉对多线程处理的不多,都不是很理想。封装完的第一个版本,想法比较简单,使用一个单例模式,对应一个连接,多线程查询的时候都是在这个链接上完成,如下简略代码
但实际使用中发现只要多线程一开就报错,一般就是lost connect之类的错误,开始以为就是单纯的连接断开,所以在连接上面做了一些文章,每次查询的时候使用ping确定连接是否正常,具体ping怎么写我这里就不赘述了,网上有很多文章,加完了Ping,对连接设立了超时时间依然不能解决问题。
查了一下文档发现在使用多线程时mysql_real_query函数和mysql_store_result函数必须加锁,由于ping有可能造成连接重连,因此在ping里面也加上了锁,如下代码
这次再试终于不报错了,高兴了好长时间,这段代码也就没有再看,代码测试到最后的时候,加上了计时等性能测量就发现问题了,多线程和单线程的用时一样。。。。问题很明显,这个其实就是串行访问数据库的,实质上还是单线程。而且即使单线程由于加的锁比较多,速度也并不快。
重新思考了下,单连接上的多线程貌似肯定是不行了,一个连接同一时刻只能处理一个线程,想明白就好办了,改成每个线程对应一个连接就OK了,而且这样改由于连接并非共享资源,也不需要加互斥,会大大提高效率。
改完之后效果很明显啊,单线程处理8000条数据(还有各种计算)大概要30秒,10线程处理只要3秒多一点,甚是欣慰。而且,原先由于锁比较多单线程处理1000条数据大概也要20秒,现在8000要30秒,提高了很多了,还有优化的地方,不过已经满足需要了,就这样吧。
总结一下,mysql多线程的封装需要注意如下几点
1. 查询前要先Ping确保连接正常
2. 每个线程对应一个连接
3. 若线程的删除和建立比较频繁,需要在获取连接时使用连接池。
mysql Connector C/C++ 多线程封装
在网上找了好久,有很多封装,但是感觉对多线程处理的不多,都不是很理想。封装完的第一个版本,想法比较简单,使用一个单例模式,对应一个连接,多线程查询的时候都是在这个链接上完成,如下简略代码
class DbClass { public: open(....) { mysql_real_connect(mDB); } QuerySQL(....) { mysql_real_query(mDB); } protected: MYSQL* mDB; }
但实际使用中发现只要多线程一开就报错,一般就是lost connect之类的错误,开始以为就是单纯的连接断开,所以在连接上面做了一些文章,每次查询的时候使用ping确定连接是否正常,具体ping怎么写我这里就不赘述了,网上有很多文章,加完了Ping,对连接设立了超时时间依然不能解决问题。
查了一下文档发现在使用多线程时mysql_real_query函数和mysql_store_result函数必须加锁,由于ping有可能造成连接重连,因此在ping里面也加上了锁,如下代码
class DbClass { public: open(....) { mysql_real_connect(mDB); } ping() { mutex.lock(); mysql_ping(); mutex.unlock(); } QuerySQL(....) { mutex.lock(); mysql_real_query(mDB); mutex.unlock(); } protected: MYSQL* mDB; }
这次再试终于不报错了,高兴了好长时间,这段代码也就没有再看,代码测试到最后的时候,加上了计时等性能测量就发现问题了,多线程和单线程的用时一样。。。。问题很明显,这个其实就是串行访问数据库的,实质上还是单线程。而且即使单线程由于加的锁比较多,速度也并不快。
重新思考了下,单连接上的多线程貌似肯定是不行了,一个连接同一时刻只能处理一个线程,想明白就好办了,改成每个线程对应一个连接就OK了,而且这样改由于连接并非共享资源,也不需要加互斥,会大大提高效率。
class DbClass { public: MYSQL*open(....) { MYSQL* pDB; mysql_real_connect(pDB); return pDB; } ping(MYSQL* pDB) { mysql_ping(pDB); } QuerySQL(MYSQL* pDB, .....) { mysql_real_query(pDB); } close(MYSQL* pDB) { mysql_close(pDB); } } work_thread() { MYSQL* pDB = DbClass::open(); //应该是单例,这里就用static示意一下 ..... DbClass::ping(pDB); DbClass::QuerySQL(pDB); ..... DbClass::close(pDB); }
改完之后效果很明显啊,单线程处理8000条数据(还有各种计算)大概要30秒,10线程处理只要3秒多一点,甚是欣慰。而且,原先由于锁比较多单线程处理1000条数据大概也要20秒,现在8000要30秒,提高了很多了,还有优化的地方,不过已经满足需要了,就这样吧。
总结一下,mysql多线程的封装需要注意如下几点
1. 查询前要先Ping确保连接正常
2. 每个线程对应一个连接
3. 若线程的删除和建立比较频繁,需要在获取连接时使用连接池。
相关文章推荐
- 20151202 c语言小代码
- C语言基础,排序算法之冒泡排序算法
- Arduino 平台与C语言程序设计-week3-Arduino Programs-Lesson1
- MySQL Connector/C++入门教程(上)
- 求字符串的最长无重复字符子串(C++)
- C++容器类是什么意思? 简单易懂
- C++中容器跟模板有什么异同么?用简单易懂的话
- 读取Windows桌面图标的名字和位置,32bit程序读取64bit进程
- Arduino 平台与C语言程序设计-week2-C Programming-Lesson3
- Effictive c++条款38-40
- 给C++初学者的50个忠告
- Template(模板)设计模式
- Arduino 平台与C语言程序设计-week2-C Programming-Lesson2
- Arduino 平台与C语言程序设计-week2-C Programming-Lesson1
- C&C++ 结构体,类 区别
- C++类与对象基础
- LeetCode Reverse Bits 的C++解决4ms
- hdu 1350 Taxi Cab Scheme(二分匹配)
- C-054.学习OC之前,需要掌握和理解的C语言的基础部分基本写完了
- C语言知识整理(1):简介