最小linux web服务器系统,TinyWebServer:一个Linux下C++轻量级Web服务器(中)

本文详细介绍了TinyWebServer中数据库连接池的实现,利用C++11的静态局部变量实现单例模式,确保全局只有一个数据库连接池。同时,通过互斥锁和信号量确保线程安全,实现多线程环境下对数据库连接的高效管理。文章还提及了定时器模块和日志模块的设计思想,包括异步写日志的实现和定时检查无响应连接的机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好的,TinyWebServer我们讲了八个模块中的5个,还剩下数据库mysql模块,定时器timer模块,日记log模块。

(更新中~~~~~~)

mysql模块

项目中有简单的注册和登录功能,所以要使用到数据库。那么mysql模块就是数据库相关的模块,主要的其实就是数据库连接池。

首先数据库连接池是只有一个的,那么怎么保证从项目的每一个地方获取都是这个唯一的一个数据库连接池呢?欸,想到什么了?单例模式。在这里我们使用Cpp11下简洁的静态局部变量实现单例模式:

connection_pool* connection_pool::GetInstance() {

static connection_pool connPool;

return &connPool;

}

原理是是C++11标准规定了当一个线程正在初始化一个变量的时候,其他线程必须得等到该初始化完成以后才能访问它。

OK我们上面解决了池子的问题,接下来我们考虑到,WebServer要有一定的并发度,所以我们要有多个数据库连接资源放在数据库连接池,当任务线程需要数据库连接的时候就向池子申请一个。好的,那么我们便有了一个问题:怎样保证数据库连接的线程安全?

我们先得有一个保存数据库连接的数据结构list,当然我们得先保证池子(或者说list的安全)的线程安全,所以有一个池子的互斥锁lock,然后我们保证list中连接资源的安全,所以再有一个信号量reserve,用于管理池子的空闲连接数。

有了这两个池子接下来的就是比较常规的做法了:在获取/归还数据库连接资源前先用互斥锁对池子加锁,然后用信号量保证list空闲连接资源数。

2b65ef29a5872cc0e4771c25889edd04.gif

6a087676c59fa8b19d76e6bb55a32902.gif

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7

8 #include"sql_connection_pool.h"

9

10 using namespacestd;11

12 //构造函数

13 connection_pool::connection_pool() {14 this->CurConn = 0;15 this->FreeConn = 0;16 this->MaxConn = 0;17 }18

19 //单例模式,静态

20 connection_pool*connection_pool::GetInstance() {21 staticconnection_pool connPool;22 return &connPool;23 }24

25 //真正的初始化函数

26 void connection_pool::init(string url, string User, string PassWord, string DBName, int Port, unsigned intMaxConn) {27 this->url =url;28 this->Port =Port;29 this->User =User;30 this->PassWord =PassWord;31 this->DatabaseName =DBName;32

33 //先互斥锁锁住池子,创造MaxConn数据库链接

34 lock.lock();35 for (int i = 0; i < MaxConn; i++) {36 //新创建一个连接资源

37 MYSQL* con =NULL;38 con =mysql_init(con);39

40 if (con ==NULL) {41 cout << "mysqlinit Error:" << mysql_error(con)<

45 con = mysql_real_connect(con, url.c_str(), User.c_str(), PassWord.c_str(), DBName.c_str(), Port, NULL, 0);46 if (con ==NULL) {47 cout << "mysql connect Error:" << mysql_error(con) <

51 //把这个资源放入链表

52 connList.push_back(con);53 ++FreeConn;54 }55

56 //初始化信号量和池子数量

57 reserve =sem(FreeConn);58 this->MaxConn =FreeConn;59

60 lock.unlock();61 }62

63 //请求获取一个连接资源

64 MYSQL*connection_pool::GetConnection() {65 MYSQL* con =NULL;66

67 if (connList.size() == 0) returnNULL;68

69 //请求一个资源,互斥锁/信号量 准备

70 reserve.wait();71 lock.lock();72

73 con = connList.front(); //从链表头取得一个资源

74 connList.pop_front();75

76 --FreeConn;77 ++CurConn;78

79 lock.unlock();80 returncon;81 }82

83 //获取空闲连接数

84 intconnection_pool::GetFreeConn() {85 return this->FreeConn;86 }87

88 //释放当前连接资源con

89 bool connection_pool::ReleaseConnection(MYSQL*con) {90 if (con == NULL) return false;91 lock.lock();92

93 connList.push_back(con);94 ++FreeConn;95 --CurConn;96

97 reserve.post();98 lock.unlock();99

100 return true;101 }102

103 //析构函数

104 connection_pool::~connec

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值