linux mysql 连接池

/*=============================================================================
#     FileName: Lock.h
#         Desc: delare Lock Class
#       Author: Pugna
#        Email: 860009944@qq.com
#     HomePage: http://www.cnblogs.com/pugna/
#      Version: 0.0.1
#   LastChange: 2014-10-22 18:05:19
#      History:
=============================================================================*/
#ifndef _LOCAL_LOCK_H_
#define _LOCAL_LOCK_H_

#include <pthread.h>

class RWLock{
    public:
        RWLock(){pthread_rwlock_init(&rwlock,NULL);}
        ~RWLock(){pthread_rwlock_destroy(&rwlock);}
        void RLock(){pthread_rwlock_rdlock(&rwlock);}
        void WLock(){pthread_rwlock_wrlock(&rwlock);}
        void UnLock(){pthread_rwlock_unlock(&rwlock);}
    private:
        pthread_rwlock_t rwlock;
};

class MutexLock{
    public:
        MutexLock(){pthread_mutex_init(&lock,NULL);}
        ~MutexLock(){pthread_mutex_destroy(&lock);}
        void Lock(){pthread_mutex_lock(&lock);}
        void UnLock(){pthread_mutex_unlock(&lock);}
    private:
        pthread_mutex_t lock;
};

template<class ClockObj>class LocalLock{
    public:
        LocalLock(ClockObj& obj):m_lock(obj){m_lock.Lock();}
        ~LocalLock(){m_lock.UnLock();}
    private:
        ClockObj & m_lock;
};
typedef LocalLock<MutexLock> LocalMutexLock;

template<class ClockObj>class LocalReadLock{
    public:
        LocalReadLock(ClockObj& obj):m_lock(obj){m_lock.RLock();}
        ~LocalReadLock(){m_lock.UnLock();}
    private:
        ClockObj & m_lock;
};
typedef LocalReadLock<RWLock> LocalRLock;

template<class ClockObj>class LocalWriteLock{
    public:
        LocalWriteLock(ClockObj& obj):m_lock(obj){m_lock.WLock();}
        ~LocalWriteLock(){m_lock.UnLock();}
    private:
        ClockObj & m_lock;
};
typedef LocalWriteLock<RWLock> LocalWLock;

#endif
/*=============================================================================
#     FileName: mysqlconnpool.h
#         Desc: declare mysqlconnpool class
#       Author: Pugna
#        Email: 860009944@qq.com
#     HomePage: http://www.cnblogs.com/pugna/
#      Version: 0.0.1
#   LastChange: 2014-10-21 15:14:31
#      History:
=============================================================================*/
#ifndef _MYSQLCONN_POOL_H
#define _MYSQLCONN_POOL_H

#include <mysql/mysql.h>
#include <pthread.h>
#include <string>
#include <queue>
#include "../common/Lock.h"

using namespace std;

class mysqlconnpool{
    public:
        mysqlconnpool(string url,int port,string user,string pwd,string db,string encode,int minSize=10,int maxSize=100);
        ~mysqlconnpool();
    
        bool Init();
        void Uninit();

        
        MYSQL * CreateConn();
        bool DeleteConn(MYSQL *conn);
        bool PopConn(MYSQL * &conn);
        bool PushConn(MYSQL * &conn);
        void getCurSize(int & n);
    private:
        int maxSize;
        int curSize;
        int minSize;
        string username;
        string password;
        string url;
        int port;
        string db;
        string encode;
        MutexLock  mutexLock;
        queue<MYSQL*>connQueue;
};

template<class ConnPool>class MysqlConn{
    public:
        MysqlConn(ConnPool & obj):conn(obj){flag=conn.PopConn(pMysql)?true:false;}
        ~MysqlConn(){if(flag)conn.PushConn(pMysql);}
    private:
        bool flag;
        ConnPool & conn;
    public:
        MYSQL * pMysql;
};

typedef MysqlConn<mysqlconnpool> LocalMysqlConn;

#endif
/*=============================================================================
#     FileName: mysqlconnpool.cpp
#         Desc: Functions of MysqlConnPool
#       Author: Pugna
#        Email: 860009944@qq.com
#     HomePage: http://www.cnblogs.com/pugna/
#      Version: 0.0.1
#   LastChange: 2014-10-21 19:48:53
#      History:
=============================================================================*/
#include <stdexcept>
#include <exception>
#include <stdio.h>
#include "mysqlconnpool.h"
#include "../common/Lock.h"


mysqlconnpool::mysqlconnpool(string url,int port,string username,string pwd,string db,string encode,int minSize,int maxSize):
    url(url)
    ,port(port)
    ,maxSize(maxSize)
    ,minSize(minSize)
    ,curSize(0)
    ,username(username)
    ,password(pwd)
    ,db(db)
    ,encode(encode)
{
}

mysqlconnpool::~mysqlconnpool(){
}

bool mysqlconnpool::Init(){
    LocalMutexLock lock(mutexLock);
    if(minSize<=0)
        return false;
    for(int i=0;i<minSize;i++){
        MYSQL * pMysql=CreateConn();
        if(pMysql==NULL)
            return false;
        connQueue.push(pMysql);
        curSize++;
    }
    if(curSize==minSize)
        return true;
    else
        return false;
}    

void mysqlconnpool::Uninit(){
    LocalMutexLock lock(mutexLock);
    if(!connQueue.empty()){
        do{
            MYSQL * pMysql=connQueue.front();
            mysql_close(pMysql);
            connQueue.pop();
        }while(!connQueue.empty());
    }
}

MYSQL * mysqlconnpool::CreateConn(){
    MYSQL * pMysql=mysql_init(NULL);
    if(pMysql==NULL){
        return NULL;
    }
    char value=1;
    if(0==mysql_options(pMysql,MYSQL_OPT_RECONNECT,&value)){
        if(mysql_real_connect(pMysql , url.c_str(), username.c_str(), password.c_str(), db.c_str(), port, NULL, 0)){
            if(0==encode.length()&&!mysql_set_character_set(pMysql,encode.c_str())){
                printf("set character false\r\n");
            }
            else{
                return pMysql;
            }
        }
        else{
            printf("connect error\r\n");
        }
    }
    else{
        printf("optione error\r\n");
    }
    mysql_close(pMysql);
    return NULL;
}

bool mysqlconnpool::PushConn(MYSQL * &conn){
    LocalMutexLock lock(mutexLock);
    if(curSize>=maxSize)
    {
        mysql_close(conn);
        conn=NULL;
        return false;
    }
    connQueue.push(conn);
    curSize++;
    return true;
}

bool mysqlconnpool::PopConn(MYSQL * &conn){
    {
        LocalMutexLock lock(mutexLock);
        if(curSize>0){
            conn=connQueue.front();
            connQueue.pop();
            curSize--;
            return true;
        }
    }
    conn=CreateConn();
    if(NULL!=conn)
        return true;
    else
        return false;
}

void mysqlconnpool::getCurSize(int & n){
    LocalMutexLock lock(mutexLock);
    n=curSize;
}
/*=============================================================================
#     FileName: client.cpp
#         Desc: test mysqlconnpool
#       Author: Pugna
#        Email: 860009944@qq.com
#     HomePage: http://www.cnblogs.com/pugna/
#      Version: 0.0.1
#   LastChange: 2014-10-21 22:13:35
#      History:
=============================================================================*/
#include <stdio.h>
#include <pthread.h>
#include "../mysqlconnpool/mysqlconnpool.h"

static const string url="127.0.0.1";
static const string username="root";
static const string password="123456";
static const string dbname="test";
static const int port=3306;
static const string encodetype="";

static const int threadNum=100;


mysqlconnpool conn(url,port,username,password,dbname,encodetype,10,1000);

void * TestThread(void * LpVoid){
    LocalMysqlConn connPool(conn);
    if(NULL==connPool.pMysql){
        printf("thread:%p,conn null\r\n");
        connPool.pMysql=conn.CreateConn();
        if(NULL==connPool.pMysql){
            printf("thread:%p,no mysql\r\n");
            pthread_exit(NULL);
        }
        else{
            printf("thread:%p,get new mysql\r\n");
        }
    }
    else{
        printf("mysql:%p,thread:%p\r\n",connPool.pMysql,pthread_self());
        if(0==mysql_query(connPool.pMysql,"update user set point=point+1 where name=\'lantun\';")){
            printf("thread:%p,query ok!\r\n",pthread_self());
        }
        else{
            printf(mysql_error(connPool.pMysql));
        }
    }
    pthread_exit(NULL);
}

int main(){
    pthread_t threadID[threadNum];

    conn.Init();
    int tdCreated=0;
    for(int i=0;i<threadNum;i++){
        if(0!=pthread_create(&threadID[i],NULL,TestThread,NULL)){
            printf("create thread false\r\n");
            break;
        }
        else
            tdCreated++;
    }
    //wate for all threads exit.
    for(int i=0;i<tdCreated;i++){
        pthread_join(threadID[i],NULL);
    }
    int mysqlNum=0;
    conn.getCurSize(mysqlNum);
    printf("mysql Num:%d\r\n",mysqlNum);
    conn.Uninit();
    return 0;
}
#=============================================================================
#     FileName: Makefile
#         Desc: :
#       Author: Pugna
#        Email: 860009944@qq.com
#     HomePage: http://www.cnblogs.com/pugna/
#      Version: 0.0.1
#   LastChange: 2014-10-21 17:00:26
#      History:
#=============================================================================
all: 
    g++ -g ../mysqlconnpool/*.* *.cpp -L /usr/lib64/mysql/ -lmysqlclient_r -lpthread -o client.o
clean:
    rm *.o

 

posted @ 2014-10-27 21:28  pugna  阅读(961)  评论(0编辑  收藏  举报