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