From 9855ff4f915c8959ca27c2e95faeb3cf6a288580 Mon Sep 17 00:00:00 2001
From: lzz <xiguabobo_2020@qq.com>
Date: 星期六, 09 十一月 2024 16:07:13 +0800
Subject: [PATCH] 添加

---
 Server/王琨元/code/ConnectionPool.cpp |  216 +++++++++++++++++++++++------------------------------
 1 files changed, 93 insertions(+), 123 deletions(-)

diff --git "a/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp" "b/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp"
index 367a7f1..2fff64c 100644
--- "a/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp"
+++ "b/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp"
@@ -1,131 +1,101 @@
+#include "stdafx.h"
 #include "ConnectionPool.h"
-ConnectionPool::ConnectionPool()
-{
-	if (!parseXmlFile())
-		return;
-	for (m_num = 0; m_num < m_minSize;) {
-		bool flag = addConnection();
-		if (!flag) {
-			return;
-		}
-	}
-	// 如果子线程的任务函数是类的非静态函数,我们需要指定任务函数的地址和任务函数的所有者
-	thread producer(&ConnectionPool::productConnection, this); // 创建连接
-	thread recycler(&ConnectionPool::recycleConnection, this); // 检测并销毁连接
-															   // 线程分离,防止阻塞主线程
-	producer.detach();
-	recycler.detach();
+
+
+ConnectionPool::ConnectionPool() {
+
+
+    m_min_conn = 5; // 假设最小连接数为 5
+    m_max_conn = 10; // 假设最大连接数为 10
+    m_timeout = 1000; // 假设连接超时时间为 1000 毫秒
+    max_del_time = 60000; // 假设最大空闲时间为 60000 毫秒
+
+    for (int i = 0; i < m_min_conn; i++) {
+        addConnection();
+    }
+    // 创建一个线程,对连接数进行监控 ,连接数不足就再继续创建
+    thread producer(&ConnectionPool::produce, this);
+    // 对连接数进行监控 ,如果有太多空闲得线程 ,那么就对其进行销毁
+    thread recycler(&ConnectionPool::recycle, this);
+
+    // 线程分离
+    producer.detach();
+    recycler.detach();
 }
-ConnectionPool::~ConnectionPool()
-{
-	while (!m_connections.empty()) {
-		MysqlConn* conn = m_connections.front();
-		m_connections.pop();
-		delete conn;
-	}
+
+
+ConnectionPool::~ConnectionPool() {
+    while (!m_connkQueue.empty()) {
+        MysqlConn* conn = m_connkQueue.front();
+        m_connkQueue.pop();
+        delete conn;
+    }
 }
-bool ConnectionPool::parseXmlFile()
-{
-	TiXmlDocument xml("mysql.xml");
-	// 加载文件
-	bool res = xml.LoadFile();
-	if (!res) {
-		return false; // 提示
-	}
-	// 根
-	TiXmlElement* rootElement = xml.RootElement();
-	TiXmlElement* childElement = rootElement->FirstChildElement("mysql");
-	// 读取信息
-	m_ip = childElement->FirstChildElement("ip")->GetText();
-	m_port = static_cast<unsigned short>(stoi(string(childElement->FirstChildElement("port")->GetText())));
-	m_user = childElement->FirstChildElement("username")->GetText();
-	m_passwd = childElement->FirstChildElement("password")->GetText();
-	m_dbName = childElement->FirstChildElement("dbName")->GetText();
-	m_minSize = static_cast<int>(stoi(string(childElement->FirstChildElement("minSize")->GetText())));
-	m_maxSize = static_cast<int>(stoi(string(childElement->FirstChildElement("maxSize")->GetText())));
-	m_maxIdleTime = static_cast<int>(stoi(string(childElement->FirstChildElement("maxIdleTime")->GetText())));
-	m_timeout = static_cast<int>(stoi(string(childElement->FirstChildElement("timeout")->GetText())));
-	return true;
+
+void ConnectionPool::addConnection() {
+    MysqlConn* conn = new MysqlConn();
+    if (!conn->isConnected()) {
+        cout << "ConnectionPool connect to mysql is failed!" << endl;
+        delete conn;
+        return;
+    }
+    conn->refreshActiveTime();
+    m_connkQueue.push(conn);
+    m_cond.notify_one();   // 唤醒一个线程
 }
-bool ConnectionPool::addConnection()
-{
-	MysqlConn* conn = new MysqlConn;
-	bool res = conn->connect(m_user, m_passwd, m_dbName, m_ip, m_port);
-	if (res) {
-		// 刷新空闲时间
-		conn->refreashAliveTime();
-		m_connections.push(conn);
-		++m_num;
-		return true;
-	}
-	else {
-		delete conn;
-		return false; // 提示
-	}
+
+void ConnectionPool::produce() {
+    while (true) {
+        unique_lock<mutex> lock(m_mutex);
+        while (m_connkQueue.size() >= m_min_conn) { // 连接队列的数量大于最小的连接数
+            m_cond.wait(lock);
+        }
+        addConnection();
+    }
 }
-void ConnectionPool::productConnection()
-{
-	while (true) {
-		unique_lock<mutex> lc(m_mutex);
-		m_cond.wait(lc, [this]() {return m_connections.empty(); });
-		if (m_num < m_maxSize) {
-			bool flag = addConnection();
-			if (!flag) {
-				return;
-			}
-		}
-		// 唤醒
-		m_cond1.notify_all();
-	}
+
+// 删除空闲连接
+void ConnectionPool::recycle() {
+    while (true) {
+        this_thread::sleep_for(chrono::milliseconds(500));   // 休眠 500 ms
+        unique_lock<mutex> lock(m_mutex);
+        while (m_connkQueue.size() > m_min_conn) {
+            MysqlConn* conn = m_connkQueue.front();
+            if (conn->getActiveTime() >= max_del_time) {
+                m_connkQueue.pop();
+                delete conn;
+            }
+            else {
+                break;
+            }
+        }
+    }
 }
-void ConnectionPool::recycleConnection()
-{
-	while (true) {
-		// 休眠一段时间 0.5s
-		this_thread::sleep_for(milliseconds(500));
-		lock_guard<mutex> lc(m_mutex);
-		while (!m_connections.empty() && m_num > m_minSize) {
-			MysqlConn* conn = m_connections.front();
-			if (conn->getAliveTime() >= m_maxIdleTime) {
-				m_connections.pop();
-				delete conn;
-				--m_num;
-			}
-			else {
-				break;
-			}
-		}
-	}
+
+shared_ptr<MysqlConn> ConnectionPool::getMysqlConn() {
+    unique_lock<mutex> lock(m_mutex);
+    while (m_connkQueue.empty()) {
+        // 如果等待一段时间后,队列还是为空,返回一个 null
+        if (cv_status::timeout == m_cond.wait_for(lock, chrono::milliseconds(m_timeout))) {
+            if (m_connkQueue.empty()) return nullptr;
+        }
+    }
+    shared_ptr<MysqlConn> connPtr(move(m_connkQueue.front()), [this](MysqlConn* conn) {
+        unique_lock<mutex> lock(m_mutex);
+        conn->refreshActiveTime();
+        m_connkQueue.push(conn);
+        });
+    m_connkQueue.pop();
+    m_cond.notify_one();   // 唤醒阻塞的生产者线程,开始生产
+    return connPtr;
 }
-ConnectionPool* ConnectionPool::getConnectPool()
-{
-	// 不使用互斥锁的线程安全的懒汉模式
-	static ConnectionPool pool; // 只在第一次调用函数时初始化
-	return &pool;
+void ConnectionPool::description() {
+    cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
+        << m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". "
+        << max_del_time << endl;
 }
-shared_ptr<MysqlConn> ConnectionPool::getConnection()
-{
-	unique_lock<mutex> lc(m_mutex);
-	while (m_connections.empty()) {
-		if (cv_status::timeout == m_cond1.wait_for(lc, chrono::milliseconds(m_timeout))) {
-			if (m_connections.empty()) {
-				// cout << "out of time" << endl;
-				return nullptr; // 结束  // 提示
-								// continue; // 利用while配合continue 继续阻塞
-			}
-		}
-	}
-	// 要指定删除器destructor,来保证连接的归还
-	shared_ptr<MysqlConn> conn(m_connections.front(), [this](MysqlConn* conn) {
-		// 加锁保证队列线程安全
-		// m_mutex.lock(); // 1
-		unique_lock<mutex> lc(m_mutex); // 2
-		// lock_guard<mutex> lc(m_mutex); // 3
-		conn->refreashAliveTime();
-		m_connections.push(conn);
-		// m_mutex.unlock(); // 1
-		});
-	m_connections.pop();
-	m_cond.notify_all();
-	return conn;
-}
+
+ConnectionPool* ConnectionPool::getInstance() {
+    static ConnectionPool connPool;
+    return &connPool;
+}
\ No newline at end of file

--
Gitblit v1.8.0