当前位置:网站首页>Database connection pool: Code Directory
Database connection pool: Code Directory
2022-06-22 15:05:00 【_ Soren】
Preface
of MySQL Database programming 、 Multithreaded programming 、 Thread mutual exclusion and synchronous communication operation 、 Intelligent pointer 、 Design patterns 、 Containers, etc. these technologies are C++ Language level can be realized directly , Therefore, the project is selected directly in windows On the platform 【virtual studio 2022】 Development .
List of articles
The header file
public.h
#pragma once
#include<iostream>
#define LOG(str) \ std::cout << __FILE__ << ":" << __LINE__ << " " << \ __TIMESTAMP__ << " : " << str << std::endl;
Connection.h
// Realization MySQL Operation of database
#include <mysql.h>
#include <string>
#include <ctime>
using namespace std;
// Database operation class
class Connection
{
public:
// Initialize database connection
Connection();
// Release database connection resources
~Connection();
// Connect to database
bool connect(string ip,
unsigned short port,
string user,
string password,
string dbname);
// update operation insert、delete、update
bool update(string sql);
// Query operation select
MYSQL_RES* query(string sql);
// Refresh the starting idle time of the connection
void refreshAliveTime();
// Return to the time of survival
clock_t getAliveTime() const;
private:
MYSQL* _conn; // Represents and MySQL Server A connection of
clock_t _aliveTime; // Record the survival time after entering the idle state
};
CommonConnectionPool.h
#pragma once
// Implement the connection pool function module
#include<iostream>
#include<string>
#include<queue>
#include<mutex>
#include<atomic>
#include<thread>
#include<memory>
#include<functional>
#include<condition_variable>
#include "Connection.h"
using namespace std;
class ConnectionPool
{
public:
// Get connection pool object instance Static
static ConnectionPool* getConnectionPool();
// Provide an interface to the outside , Provide an idle connection
shared_ptr<Connection> getConnection();
private:
ConnectionPool(); // The singleton pattern Constructor privatization
bool loadConfigFile(); // Load profile
// Producer thread function , Responsible for the production of new connections
void produceConnectionTask();
// Recycling thread functions , Responsible for recycling redundant idle connections
void scannerConnectionTask();
string _ip; // MySQL Of IP Address
unsigned short _port; // MySQL Port number
string _username; // MySQL Login user name of
string _password; // MySQL Login password for
string _dbname; // Database name
int _initSize; // The initial number of connections to the connection pool
int _maxSize; // The maximum number of connections in the connection pool
int _maxIdleTime; // The maximum waiting time of the connection pool
int _connectionTimeOut; // The timeout for the connection pool to obtain connections
queue<Connection*> _connectionQue; // Storage MySQL Connected queue
mutex _queueMutex; // Maintain thread safe mutexes for connection queues
atomic_int _connectionCnt; // Record the... Created by the connection connection Total connections for , No more than _maxSize
condition_variable cv; // Connect the communication between the production thread and the consumption thread
};
Source file
Connection.cpp
#include <mysql.h>
#include <string>
#include "Connection.h"
#include "public.h"
using namespace std;
// Initialize database connection
Connection::Connection()
{
_conn = mysql_init(nullptr);
}
// Release database connection resources
Connection::~Connection()
{
if (_conn != nullptr)
mysql_close(_conn);
}
// Connect to database
bool Connection::connect(string ip, unsigned short port, string user,
string password, string dbname)
{
MYSQL* p = mysql_real_connect(_conn, ip.c_str(), user.c_str(),
password.c_str(), dbname.c_str(), port, nullptr, 0);
return p != nullptr;
}
// update operation insert、delete、update
bool Connection::update(string sql)
{
if (mysql_query(_conn, sql.c_str()))
{
LOG(" Update failed :" + sql);
return false;
}
return true;
}
// Query operation select
MYSQL_RES* Connection::query(string sql)
{
if (mysql_query(_conn, sql.c_str()))
{
LOG(" The query fails :" + sql);
return nullptr;
}
return mysql_use_result(_conn);
}
// Refresh the starting idle time of the connection
void Connection::refreshAliveTime()
{
_aliveTime = clock();
}
// Return to the time of survival
clock_t Connection::getAliveTime() const
{
return clock() - _aliveTime;
}
mysql.ini
# Configuration file of database connection pool
ip=127.0.0.1
port=3306
username=root
password=123456
dbname=chat
initSize=10
maxSize=1024
# The maximum idle time is seconds by default
maxIdleTime=60
# Connection timeout , In milliseconds
connectionTimeOut=100
CommonConnectionPool.cpp
#include "CommonConnectionPool.h"
#include "public.h"
// Thread safe lazy singleton mode function interface
ConnectionPool* ConnectionPool::getConnectionPool()
{
// Static local variables , Compiler automatic lock and unlock
static ConnectionPool pool;
return& pool;
}
// Load configuration items from the configuration file
bool ConnectionPool::loadConfigFile()
{
FILE* pf = fopen("mysql.ini", "r");
if (pf == nullptr)
{
LOG("mysql.ini file is not exist!");
return false;
}
while (!feof(pf))
{
char line[1024] = {
0 };
fgets(line, 1024, pf);
string str = line;
int idx = str.find('=', 0);
if (-1 == idx) // Invalid configuration
{
continue;
}
int endidx = str.find('\n', idx);
string key = str.substr(0, idx);
string value = str.substr(idx + 1, endidx - idx - 1);
if (key == "ip")
{
_ip = value;
}
else if (key == "port")
{
_port = atoi(value.c_str());
}
else if (key == "username")
{
_username = value;
}
else if (key == "password")
{
_password = value;
}
else if (key == "dbname")
{
_dbname = value;
}
else if (key == "initSize")
{
_initSize = atoi(value.c_str());
}
else if (key == "maxSize")
{
_maxSize = atoi(value.c_str());
}
else if (key == "maxIdleTime")
{
_maxIdleTime = atoi(value.c_str());
}
else if (key == "connectionTimeOut")
{
_connectionTimeOut = atoi(value.c_str());
}
}
return true;
}
// Constructor for connection pool
ConnectionPool::ConnectionPool()
{
// 1. Load configuration items
if (!loadConfigFile())
{
return;
}
// 2. Create initial quantity connection
for (int i = 0; i < _initSize; ++i)
{
Connection* p = new Connection();
p->connect(_ip, _port, _username, _password, _dbname);
p->refreshAliveTime(); // Refresh the start time of idle
_connectionQue.push(p);
_connectionCnt++;
}
// 3. Start a new thread as the producer thread
thread produce(std::bind( & ConnectionPool::produceConnectionTask, this));
produce.detach(); // The guardian thread ( Detaching threads )
// 4. Start a new thread , Scan over maxIdleTime Of free connections , Recycle excess connections
thread scanner(std::bind(&ConnectionPool::scannerConnectionTask, this));
scanner.detach();
}
// producer : Running on a separate thread , Responsible for production connection
void ConnectionPool::produceConnectionTask()
{
// loop ( Keep listening )
for (; ;)
{
unique_lock<mutex> lock(_queueMutex);
while (!_connectionQue.empty())
{
cv.wait(lock); // The queue is not empty , The production thread enters the waiting queue for the condition variable
}
// The number of connections has not reached the maximum , Continue creating new connections
if (_connectionCnt < _maxSize)
{
Connection* p = new Connection();
p->connect(_ip, _port, _username, _password, _dbname);
p->refreshAliveTime(); // Refresh the start time of idle
_connectionQue.push(p);
_connectionCnt++;
}
// Wake up all threads in the waiting queue
cv.notify_all(); // Notify consumer thread , You can consume and connect
}
}
// Provide an interface to the outside , Provide an idle connection
shared_ptr<Connection> ConnectionPool::getConnection()
{
unique_lock<mutex> lock(_queueMutex);
while (_connectionQue.empty())
{
// Not directly sleep
// When I wake up after a timeout, I find that it is still empty , Just go back to nullptr
if (cv_status::timeout == cv.wait_for(lock, std::chrono::milliseconds(_connectionTimeOut)))
{
if (_connectionQue.empty())
{
LOG(" Getting idle connection timed out ... Failed to get connection !");
return nullptr;
}
}
}
/* because shared_ptr At the time of deconstruction , Will be able to Connection Resource Direct delete fall , Equivalent to calling Connection Destructor of ,Connection I was close It fell off , So you need to customize how smart pointers release resources , Instead, return the resource to the queue */
shared_ptr<Connection> sp(_connectionQue.front(),
[&](Connection* pcon) {
// This is called in the server application thread. , Thread safety needs to be considered
unique_lock<mutex> lock(_queueMutex);
pcon->refreshAliveTime(); // Refresh the start time of idle
_connectionQue.push(pcon);
});
_connectionQue.pop();
// Consume the last one in the queue Connection, The producer thread is notified of the production connection
cv.notify_all();
return sp;
}
// Scan over maxIdleTime Of free connections , Recycle excess connections
void ConnectionPool::scannerConnectionTask()
{
for (; ;)
{
// adopt sleep Simulate the timing effect
this_thread::sleep_for(std::chrono::seconds(_maxIdleTime));
// Scan the entire queue , Release more than connections
unique_lock<mutex> lock(_queueMutex);
while (_connectionCnt > _initSize)
{
Connection* p = _connectionQue.front();
if (p->getAliveTime() >= (_maxIdleTime * 1000))
{
_connectionQue.pop();
_connectionCnt--;
delete p; // call ~Connection();
}
else
{
break; // The connection of the team head does not exceed _maxIdleTime, There must be none in the back
}
}
}
}
边栏推荐
- Redistemplate serialization
- Biden signs two new laws aimed at strengthening government cyber security
- 【毕业设计】基于半监督学习和集成学习的情感分析研究
- How to use SQL to modify in the database & delete
- 擴散模型又殺瘋了!這一次被攻占的領域是...
- Closure of groovy
- 直播出海 | 国内直播间再出爆品,「外卷」全球如何致胜
- phpStudy 2016搭建-pikachu靶场
- Perceptron of machine learning
- Unity's rich text color sets the color to be fully transparent
猜你喜欢
![[graduation project] Research on emotion analysis based on semi supervised learning and integrated learning](/img/02/33d7b6a5bc01737c5dbeb944202a66.jpg)
[graduation project] Research on emotion analysis based on semi supervised learning and integrated learning

基于SSH框架甜品商城管理系统【源码+数据库】
![[Software Engineering] design module](/img/08/d55af729a8241e109fdeb96c896670.png)
[Software Engineering] design module

利用图片实现APP元素定位sikulix

网络地址转换NAT

数据采集之:巧用布隆过滤器提取数据摘要

Phpstudy 2016 build Pikachu range

树结构二叉树

UE4 obtains local files through blueprints

擴散模型又殺瘋了!這一次被攻占的領域是...
随机推荐
山东泰安“6·21”燃气爆炸事故后续:全面排查整治餐饮场所燃气安全隐患
Random forest of machine learning
阿里云发布CIPU,对于企业客户意味着什么?
Recommendation of individual visa free payment scheme
基于SSH框架甜品商城管理系统【源码+数据库】
The diffusion model is crazy again! This time the occupied area is
flutter video_player實現監聽和自動播放下一首歌曲
Groovy list operation
Is the encryption market a "natural disaster" or a "man-made disaster" in the cold winter?
Struggle, programmer chapter 45 tenderness is like water and a good time is like a dream
Struggle, programmer -- Chapter 46 this situation can be recalled, but it was at a loss at that time
Struggle, programmer -- Chapter 44: eight hundred miles under one's command, fifty strings turning over the Great Wall
CSAPP之详解Labs
Introduction to groovy syntax
数据库连接池:代码目录
PHP内置协议(支持的协议和封装协议)
[PR] basic process
2022oracle数据库安装及使用
Struggle, programmer chapter 50: a bosom friend in the sea
D damage and safety