zoukankan      html  css  js  c++  java
  • 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. 若线程的删除和建立比较频繁,需要在获取连接时使用连接池。

  • 相关阅读:
    关于js原型链继承的一些复习
    echarts 柱状图
    js的属性监听
    改变input[type=range]的样式 动态滑动
    占位符 css
    JS简单实现:根据奖品权重计算中奖概率实现抽奖的方法
    layui navTree 动态渲染菜单组件介绍
    配置单机Kafka
    树莓派安装pip3以及扩展包的方法
    Gunicorn+Nginx+Flask项目部署
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318580.html
Copyright © 2011-2022 走看看