xPool-mysqlclientベースmysqlのc++接続プール


最近仕事を待って、暇な卵はかわいがって、C++の下でmysql接続池のこのような基礎のものさえ使ったことがないことを発見して、1名のコンピュータの卒業生として、罪悪感を深く感じて、ついに1つの考えを生んで、1つを書いてあるいは接続池を探して、私のごみのような専門の修養を強めます.
意外にも第1版を書いてメモリ管理の問題があるcoredumpがあって、半日調べて、空のポインタのメンバー関数を呼び出したことを発見して、徹底的に気絶して、その間gdb coreの中でbtのlibmysqlclientをデバッグするためです.soのmysql_real_connect呼び出し、mysqlの5.5を下ろしました.31ソースコードを何度も編集しましたが、debug版のデバッグをしようとしても成功しませんでした.问题を発见しますやはりネット上の招待状を见てsegfault 11このような问题の大半はすべて空の指针がやったので、逆にいくつかの指针の印刷の文をプラスしてやっと低級な间违いを意识して、それからdebugの过程の中で更に低級なロジックの间违いを発见して三日間やって安定した、大きな罪、自分と社会の生産力を浪費した.
過程の中で自分がうまく書けない以上、いっそ使いやすいものを探して、結果はlibzdbを発見して、いくつかのオープンソースdbの接続プールを支持して、勝手にコードを破って測定して、よくやっていません.debugの中でそのソースコードを参考にして、まだ少し啓発されています.
今のところこのソースコードはvalgrindで自分で測定して、74 KBぐらいのメモリの漏れがあって、人が改めることができることを知っているならば最も良くて、1人の菜鳥として私は自分を助けることしかできなくて、もちろんこの漏れは時間とともに線形に増加することはできなくて、これは私はやはり測定したことがあって、ある人が生産環境を使うことができるならば、面倒は私に改善の意見を出して、72時間の作品、あまりにも試練に耐えられません、現在、本機では最大152本の接続しかサポートできません.153に設定すると接続失敗を報告します.牛迫の先輩たちはこのコードを厳しく批判しました.自分も自分のレベルがあまりにも不自由だと感じています.mysqlの設置かシステムの設置の問題か分かりません.とにかくアドバイスでも問題でも投げてください.馬鹿な二品として全部受け取ります.
じょうふごう
Githubに行ってコードを見てhttps://github.com/githcx/xPool
pool.h (1 in 3)
#include <mysql.h>
#include <stdio.h>
#include <string.h>
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <pthread.h>

using std::string;
using std::vector;

class Connection;

class some{
	public:
		some(){}
		Connection * first;
		bool second;
};

class Pool{
	public:
		static int initPool(string host,string user,string pass,string dbname,int poolSize);
		static void destroyPool();

		static Connection* getConnection();
		static int releaseConnection(Connection*);
		static void lock();
		static void unlock();

		static void locke();
		static void unlocke();

		static void locki();
		static void unlocki();

		static void lockl();
		static void unlockl();


	private:

		static pthread_mutex_t mutex;
		static pthread_mutex_t execmutex;
		static pthread_mutex_t initmutex;
		static pthread_mutex_t logmutex;
		static Pool* pool_;

	private:
		some* vec;     // need an instance to init

	public:
		static string host_ ;
		static string user_ ;
		static string pass_ ;
		static string dbname_;
		static int poolSize_ ;

	public:

		Pool(string host,string user,string pass,string dbname,int poolSize);
		virtual ~Pool();
};

class QueryResult;

class Connection{
	public:
		Connection(string host,string user,string pass,string dbname);
		virtual ~Connection();

		QueryResult executeQuery(string statement);
	private:
		// MYSQL     TCP  
		MYSQL* conn;
};

class QueryResult{
	public:
		int getRowCount(){return string_table.size();}
		int getColumnCount(){return string_table[0].size();};
		string getElement(int row,int column){return string_table[row][column];}
		void addRow(const vector<string>& row){string_table.push_back(row);}
	private:
		vector<vector<string> > string_table;
};

pool.h (2 in 3)
#include "pool.h"
#include <stdlib.h>

// for DEBUG
using std::cout;
using std::endl;


// static field init
string Pool::host_ = "";
string Pool::user_ = "";
string Pool::pass_ = "";
string Pool::dbname_ = "";
int    Pool::poolSize_ = 0;
Pool*  Pool::pool_ = NULL;
pthread_mutex_t Pool::mutex;
pthread_mutex_t Pool::execmutex;
pthread_mutex_t Pool::initmutex;
pthread_mutex_t Pool::logmutex;

void Pool::lock(){
	pthread_mutex_lock(&mutex);
}

void Pool::unlock(){
	pthread_mutex_unlock(&mutex);
}

void Pool::locke(){
	pthread_mutex_lock(&execmutex);
}

void Pool::unlocke(){
	pthread_mutex_unlock(&execmutex);
}

void Pool::locki(){
	pthread_mutex_lock(&initmutex);
}

void Pool::unlocki(){
	pthread_mutex_unlock(&initmutex);
}

void Pool::lockl(){
	pthread_mutex_lock(&logmutex);
}

void Pool::unlockl(){
	pthread_mutex_unlock(&logmutex);
}



Pool::Pool(string host,string user,string pass,string dbname,int poolSize){

	vec = new some[Pool::poolSize_];


	for(int i=0; i<poolSize_; i++){
		Connection* conn = new Connection(Pool::host_,Pool::user_,Pool::pass_,Pool::dbname_);
		//std::cout << conn << std::endl;
		//std::cout << host << " " << user << " " << pass << " " << dbname << " " << poolSize << std::endl;
		if(!conn){
			cout << "xPool: new Connection Operation failed" << endl;
			exit(-1);
		}
		vec[i].first = conn;
		vec[i].second = false;
	}


}

Pool::~Pool(){
	for(int i=0;i<poolSize_;i++){
		delete vec[i].first;
	}
	delete[] vec;
	//mysql_library_end();
}

int Pool::initPool(string host,string user,string pass,string dbname,int poolSize){
	host_ = host;
	user_ = user;
	pass_ = pass;
	dbname_ = dbname;
	poolSize_ = poolSize;
	
	return 0;
}

void Pool::destroyPool(){
	if(pool_){
		delete pool_;
		pool_ = NULL;
	}
}

Connection* Pool::getConnection(){

	// init pool, open connections
	Pool::locki();
	if(pool_ == NULL){
		pthread_mutex_init(&mutex,0);
		pthread_mutex_init(&execmutex,0);

		//mysql_library_init(0,NULL,NULL);

		pool_ = new Pool(host_,user_,pass_,dbname_,poolSize_);
	}
	Pool::unlocki();

	//get connection operation
	Connection* ret = NULL;
	while(true){
		Pool::lock();
		bool flag = false;
		for(int i=0;i<poolSize_;i++){
			if(pool_->vec[i].second == false){
				pool_->vec[i].second = true;
				ret = pool_->vec[i].first;
				flag = true;
				break;
			}
		}
		if(flag == true){
			Pool::unlock();
			break;
		}
		else{
			//cout << "wait" << endl;
			Pool::unlock();
			usleep(1000);
			continue;
		}
	}
	return ret;
}

int Pool::releaseConnection(Connection* conn){
	lock();
	for(int i=0;i<poolSize_;i++){
		if(pool_->vec[i].first == conn ){
			pool_->vec[i].second = false;
			break;
		}
	}
	unlock();
	return 1;
}


Connection::Connection(string host,string user,string pass,string dbname){

	static int connectionCount = 0;
	
	//cout << "C#:" << connectionCount++ << endl;

	//      
	conn = mysql_init(NULL);

	//cout << "conn:" << conn << endl;
	
	//      tcp    ,      
	if (!mysql_real_connect(conn,"localhost", "root", "jiqim1ma", "hcx",0,NULL,0)){
		printf( "xPool: Error connecting to database: %s
",mysql_error(conn)); exit(-1); } else{ } } Connection::~Connection(){ //mysql_thread_end(); // TCP , mysql_close(conn); } QueryResult Connection::executeQuery(string statement){ //Pool::locke(); //cout << "0.start query" << endl; const char* query = statement.c_str(); //cout << "1.before mysql_real_query" << endl; //cout << "strlen=[" << strlen(query) << "]" << endl; unsigned int len = (unsigned int) strlen(query); char q[100]; strncpy(q,query,len); q[len]=0; int status = mysql_real_query(conn,q,len); //cout << "1.after mysql_real_query" << endl; if(status){ printf("Error making query: %s
", mysql_error(conn)); } else{ //printf("[%s] made...
", query); } MYSQL_RES* resultSet; //cout << "2.before mysql_store_result" << endl; resultSet = mysql_store_result(conn); //cout << "2.after mysql_store_result" << endl; //cout << "3.before mysql_fetch_row" << endl; QueryResult queryResult; while(true){ MYSQL_ROW row; if(!(row = mysql_fetch_row(resultSet))){ break; } vector<string> string_row; for(int i=0; i < mysql_num_fields(resultSet); i++){ string_row.push_back(row[i]); } queryResult.addRow(string_row); } //cout << "3.after mysql_fetch_row" << endl; //cout << "4.before mysql_free_result" << endl; mysql_free_result(resultSet); //free result after you get the result //cout << "4.after mysql_free_result" << endl; //cout << "0.finish query" << endl; //Pool::unlocke(); return queryResult; }

mine.cpp ( 3 in 3 )
#include "pool.h" 
#include <unistd.h>
#include <stdlib.h>
using std::cout;
using std::endl;

void* handler(void* arg){
	long tid = (long)arg;

	//cout << "tid =[" << tid << "]" << endl;
	Connection* conn = Pool::getConnection();

	if(!conn){
		cout << "getConnection NULL pointer" << endl;
		exit(-1);
	}
	
	//cout << "Connection.this:" << conn << endl;

	const char* query;
	query = "select * from student;";

	QueryResult queryResult = conn->executeQuery(query);

	Pool::releaseConnection(conn);

	//for(int i=0;i<queryResult.getRowCount();i++){
	//	for(int j=0;j<queryResult.getColumnCount();j++){
	//		cout << queryResult.getElement(i,j) << " ";
	//	}
	//	cout << endl;
	//}
}


int main(int argc,  char* argv[]){
	string host = "localhost";
	string user = "root";
	string pass = "jiqim1ma";
	string dbname = "hcx";
	int poolSize = 152;

	Pool::initPool(host,user,pass,dbname,poolSize);
	
	///std::cin.get();

	unsigned int count = -1;
	if(argc>1){
		count = atoi(argv[1]);
	}

	for(int i=0;i < count;i++){

		const int THREAD_COUNT = 250;
		pthread_t threads[THREAD_COUNT];
		for(long i=0;i<THREAD_COUNT;i++){
			pthread_create(&threads[i],NULL,handler,(void*)i);
			//sleep(1);
		}

		for(int i=0;i<THREAD_COUNT;i++){
			pthread_join(threads[i],0);
		}

		cout << "==============================LOOPBACK=================================" << endl;
	}

	Pool::destroyPool();



	return 0;
}

Makefile
all: sbpool

sbpool: mine.cpp pool.cpp
	g++ -g -o sbpool mine.cpp pool.cpp -lmysqlclient -lpthread

clean:
	rm -f *.o accessdb sbpool core*