TinyWebSever源码逐行注释(六)_ sql_connection.cpp

news2025/1/15 12:52:13

前言

项目源码地址
项目详细介绍

项目简介:
Linux下C++轻量级Web服务器,助力初学者快速实践网络编程,搭建属于自己的服务器.

  1. 使用 线程池 + 非阻塞socket + epoll(ET和LT均实现) + 事件处理(Reactor和模拟Proactor均实现) 的并发模型
  2. 使用状态机解析HTTP请求报文,支持解析GET和POST请求
  3. 访问服务器数据库实现web端用户注册、登录功能,可以请求服务器图片和视频文件
  4. 实现同步/异步日志系统,记录服务器运行状态
  5. 经Webbench压力测试可以实现上万的并发连接数据交换

sql_connection.cpp用于实现数据库的连接池。主要内容如下:

1.数据库连接池

  • 单例模式,保证唯一
  • list实现连接池
  • 连接池为静态大小
  • 互斥锁实现线程安全

2.校验

  • HTTP请求采用POST方式
  • 登录用户名和密码校验
  • 用户注册及多线程注册安全

原项目地址的注释较少不适合初学者,于是我将每行都加上了注释帮助大家更好的理解:

#include <mysql/mysql.h> // 包含 MySQL 库,用于和 MySQL 数据库交互
#include <stdio.h>       // 标准输入输出库
#include <string>        // C++ 字符串库
#include <string.h>      // C 字符串处理库
#include <stdlib.h>      // 标准库,包含内存分配、进程控制等
#include <list>          // C++ STL 的 list 容器,用于存储 MySQL 连接
#include <pthread.h>     // 线程库,用于多线程同步
#include <iostream>      // C++ 标准输入输出流
#include "sql_connection_pool.h" // 连接池头文件

using namespace std; // 使用标准命名空间

// 构造函数,初始化成员变量
connection_pool::connection_pool()
{
	m_CurConn = 0;  // 当前已使用的连接数
	m_FreeConn = 0; // 当前空闲的连接数
}

// 获取连接池实例(单例模式)避免重复创建连接池对象,进而管理和复用 MySQL 连接。
connection_pool *connection_pool::GetInstance()
{
	static connection_pool connPool; // 静态实例,保证全局唯一
	return &connPool; // 返回连接池的指针
}

// 构造初始化函数,设置连接池的相关配置
void connection_pool::init(string url, string User, string PassWord, string DBName, int Port, int MaxConn, int close_log)
{
	// 保存数据库连接的参数
	m_url = url;               // 数据库主机地址
	m_Port = Port;             // 端口号
	m_User = User;             // 数据库用户名
	m_PassWord = PassWord;     // 数据库密码
	m_DatabaseName = DBName;   // 数据库名
	m_close_log = close_log;   // 是否关闭日志

	// 创建最大连接数个 MySQL 连接并加入连接池
	for (int i = 0; i < MaxConn; i++)
	{
		MYSQL *con = NULL;
		con = mysql_init(con); // 初始化 MySQL 连接

		if (con == NULL) // 如果初始化失败,打印错误日志并退出程序
		{
			LOG_ERROR("MySQL Error");
			exit(1);
		}

		// 连接到 MySQL 数据库
		con = mysql_real_connect(con, url.c_str(), User.c_str(), PassWord.c_str(), DBName.c_str(), Port, NULL, 0);

		if (con == NULL) // 如果连接失败,打印错误日志并退出程序
		{
			LOG_ERROR("MySQL Error");
			exit(1);
		}

		// 将成功连接的 MySQL 连接加入连接池列表
		connList.push_back(con);
		++m_FreeConn; // 增加空闲连接数
	}

	// 初始化信号量,用于控制连接的获取和释放
	reserve = sem(m_FreeConn); 

	m_MaxConn = m_FreeConn; // 设置最大连接数
}

// 从连接池中获取一个可用的 MySQL 连接
MYSQL *connection_pool::GetConnection()
{
	MYSQL *con = NULL;

	if (0 == connList.size()) // 如果连接池为空,返回 NULL
		return NULL;

	reserve.wait(); // 等待信号量,如果没有空闲连接则等待

	lock.lock(); // 加锁,防止多线程同时操作连接池

	// 从连接池中取出一个连接
	con = connList.front(); 
	connList.pop_front(); // 移除最前面的连接

	--m_FreeConn; // 空闲连接数减少
	++m_CurConn;  // 使用中的连接数增加

	lock.unlock(); // 解锁
	return con;    // 返回获取的连接
}

// 释放当前使用的 MySQL 连接,将其放回连接池
bool connection_pool::ReleaseConnection(MYSQL *con)
{
	if (NULL == con) // 如果连接为空,返回 false
		return false;

	lock.lock(); // 加锁,防止多线程同时操作连接池

	// 将连接放回连接池
	connList.push_back(con);
	++m_FreeConn; // 空闲连接数增加
	--m_CurConn;  // 使用中的连接数减少

	lock.unlock(); // 解锁

	reserve.post(); // 释放信号量,通知等待的线程有连接可用
	return true;
}

// 销毁连接池,关闭所有 MySQL 连接
void connection_pool::DestroyPool()
{
	lock.lock(); // 加锁,防止其他线程操作连接池
	if (connList.size() > 0)
	{
		// 遍历连接池中的所有连接,逐一关闭
		list<MYSQL *>::iterator it;
		for (it = connList.begin(); it != connList.end(); ++it)
		{
			MYSQL *con = *it;
			mysql_close(con); // 关闭 MySQL 连接
		}
		m_CurConn = 0; // 重置已使用连接数
		m_FreeConn = 0; // 重置空闲连接数
		connList.clear(); // 清空连接池列表
	}

	lock.unlock(); // 解锁
}

// 返回当前空闲的连接数
int connection_pool::GetFreeConn()
{
	return this->m_FreeConn; // 返回空闲连接数
}

// 析构函数,销毁连接池,释放所有连接
connection_pool::~connection_pool()
{
	DestroyPool(); // 调用销毁连接池的函数
}

// RAII 机制,自动管理 MySQL 连接的获取和释放
connectionRAII::connectionRAII(MYSQL **SQL, connection_pool *connPool){
	*SQL = connPool->GetConnection(); // 获取一个数据库连接并赋值给传入的指针

	conRAII = *SQL; // 保存获取到的连接
	poolRAII = connPool; // 保存连接池的引用
}

// 析构函数,自动释放连接回连接池
connectionRAII::~connectionRAII(){
	poolRAII->ReleaseConnection(conRAII); // 将连接放回连接池
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2119768.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web 原生组件化方案:Web Components

你好&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 Web 组件化是一种将Web应用的UI部分拆分成可复用的独立组件的架构方法。这种方法有助于提高代码的可维护性、可重用性和可测试性。 而Web Components 标准则提供了一套原生的API&#xff0c;允许开发者创建…

TestCraft - GPT支持的测试想法生成器和自动化测试生成器

在当今快速变化的软件开发世界中&#xff0c;自动化测试已成为确保软件质量的关键环节。而随着AI技术的进步&#xff0c;越来越多的工具开始引入人工智能&#xff0c;来辅助生成测试用例和自动化测试脚本。其中&#xff0c;TestCraft&#xff0c;作为一款GPT支持的测试想法生成…

天命所归,SyntaxFlow助大圣取得真经

之前预告许久的SyntaxFlow功能已经登陆Yakit&#xff01; SyntaxFlow代码查询需要先进行项目编译。 手动编译 在前端的YakRunner界面&#xff0c;主界面或选项栏可以直接点击“编译项目”功能。 可见图中红色方框圈起的选项 编译项目的选项如下&#xff1a;必选项为项目名、…

工控机防病毒/防勒索病毒如何一步搞定?

随着勒索病毒的肆虐和内部运营泄密事件的频发&#xff0c;企业数据安全正面临着前所未有的挑战。苏州深信达网络科技有限公司&#xff0c;作为数据安全解决方案的先驱&#xff0c;推出了MCK主机加固解决方案&#xff0c;为企业数据安全提供了一道坚不可摧的防线。 MCK主机加固…

Linux:多路转接 select、poll、epoll

目录 1&#xff1a;select 1. 参数解释 2. 函数返回值 3. fd_set 4. fd_set 相关接口 5. timeval 5. 常见使用 6. 理解 select 执行过程 7. select 的特点 8. select 缺点 9. select 应用 2&#xff1a;socket 就绪条件 1. 读事件就绪&#xff08;Readable&#x…

智能优化算法-海马优化算法(SHO)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 海马优化算法 (Seahorse Optimization Algorithm, SHO) 是一种基于群体智能的元启发式优化算法&#xff0c;它模拟了海马的觅食行为、繁殖行为以及社会互动&#xff0c;用于解决复杂的优化问题。 SHO的工作机制…

精选干货!分享5款ai智能写论文软件

在当今信息爆炸的时代&#xff0c;AI智能写作工具已经成为我们写作过程中的得力助手。特别是对于学术论文的撰写&#xff0c;这些工具不仅能够提高写作效率&#xff0c;还能帮助用户生成高质量的文稿。以下是五款值得推荐的AI智能写论文软件&#xff0c;其中特别推荐千笔-AIPas…

Path系统环境变量和CLASSPATH环境变量

Path系统环境变量 概述&#xff1a;Path环境变量不是java的&#xff0c;它隶属于windows操作系统 作用&#xff1a; PATH环境变量实际上就是给windows操作系统指路的。 在Path环境变量中有很多路径&#xff0c;路径和路径之间采用 分号(;) 隔开在DOS命令窗口中输入一条DOS命…

Vscode中搭建ABAP开发环境

文章目录 前提&#xff08;在SAP系统中测试&#xff09;1.1 登录sap 系统1.2激活测服务测试1.3 添加服务 下载Vscode2.1 安装ABAP Remote filesystem 打开ABAP System3.1 按照CtrlshiftP 找到AbapFs Connect to an ABAP system 前提&#xff08;在SAP系统中测试&#xff09; 1…

2-89 基于matlab的图像去噪方法

基于matlab的图像去噪方法&#xff0c;对比了常见的几种去噪方法&#xff0c;含中值滤波&#xff0c;均值滤波&#xff0c;维纳滤波&#xff0c;高斯滤波&#xff0c;以及三种形态学滤波&#xff08;一般的&#xff0c;改进的&#xff0c;多结构元素形态学滤波&#xff09;&…

HarmonyOS开发之Tab样式(背景高亮样式)

一&#xff1a;开发环境 二&#xff1a;效果图 三&#xff1a;实现步骤 Entry Component struct TabsPage {State tabArray:string[] ["首页","分类","应用","热点","我的"]State focusIndex: number 0;State index: num…

嵌入式学习(哈希表)

哈希表中元素是由哈希函数确定的&#xff0c;将数据元素的关键字key作为自变量&#xff0c;通过一定的函数关系&#xff08;称为哈希函数&#xff09;&#xff0c;计算出的值&#xff0c;即为该元素的存储地址。 哈希函数&#xff1a;指将哈希表中元素的关键键值映射为元素存储…

局域网远程桌面工具:NoMachine 介绍、安装与使用

局域网远程桌面工具&#xff1a;NoMachine 介绍、安装与使用 NoMachine 简介Linux 安装Windows安装使用 NoMachine 简介 NoMachine是一款很常见的远程桌面工具&#xff0c;尤其在EDA领域&#xff0c;常常被用作远程接入方案。NoMachine可以用于个人远程连接&#xff0c;类似于…

4.第二阶段x86游戏实战2-CE加强修改移动速度(浮点数存放方式与转换)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

2.3.2 协程调度器实现与性能测试

LINUX 精通 8 day24 20240909 晚19&#xff1a;35 - 20: 47 课程链接地址 老师画图用的是excalidraw 可以在线 本地&#xff01; Excalidraw&#xff1a;开源实用的白板画图工具&#xff08;在线/本地安装&#xff09;-CSDN博客 2.3.2 协程调度器实现与性能测试 复习了上…

HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)

跟着该视频学习&#xff0c;记录笔记&#xff1a;【黑马程序员pink老师前端入门教程&#xff0c;零基础必看的h5(html5)css3移动端前端视频教程】https://www.bilibili.com/video/BV14J4114768?p12&vd_source04ee94ad3f2168d7d5252c857a2bf358 Day3 内容梳理&#xff1a;…

使用ChatGPT生成爆款小红书文案,有手就行!

小红书&#xff0c;作为当下热门的社交电商平台&#xff0c;以其独特的社区氛围、精准的用户画像和高粘性的互动模式&#xff0c;吸引了大量年轻用户&#xff0c;尤其是女性用户。平台上的内容风格多样&#xff0c;涵盖了美妆、时尚、生活方式等多个领域。 本文将介绍小红书平台…

为何家用无线路由器不能实现PROFINET通信?

家用无线路由器和工业通信设备到底有什么不同&#xff1f;工控人加入PLC工业自动化精英社群 首先&#xff0c;在技术上&#xff0c;两者存在明显的差异。 家用无线路由器主要是为了提供互联网接入和家庭设备间的连接&#xff0c;而PROFINET则是专为工业自动化设计的通信协议。就…

1分钟教你用AI制作美女热舞视频,收益可观,操作简单(附工具及教程资料)

美女跳舞&#xff0c;听着是不是就觉得会很哇塞&#xff1f; 不管是男的女的、老的少的都喜欢看&#xff0c;而且一般美女跳舞的账号涨粉都很快&#xff0c;势头都贼猛。 今天就给大家分享一个很热门的小副业——AI美女跳舞。 更多实操和AI绘画工具&#xff0c;可以扫描下方&…

通过SSH服务远程操作Linux(ubuntu)主机

首先SSH是什么&#xff1f;SSH&#xff08;Secure SHell&#xff09;是Linux、Unix、Mac及其他网络设备最常用的远程CLI管理协议&#xff0c;SSH使用秘钥对数据进行加密&#xff0c;保证了远程管理数据的安全性。Secure Shell (SSH) 是一种网络协议&#xff0c;允许用户通过加密…