# 【服务器】各模块的功能与实现
## 日志系统
server使用的日志系统是一个轻量级的简易日志系统。用户可以调用头文件`Log.h`中提供了四个全局函数`log_debug()`、`log_info()`、`log_warn()`、`log_error()`在控制台上输出不同级别的日志。由于日志系统全局只需要有一个,因此这里使用单例模式(线程安全的懒汉模式)来实现日志系统。日志系统在析构时需要将目前日志队列中的所有日志取出并输出。
日志系统的输出有四种级别,从低到高分别是:debug、info、warn、error,用户可以在配置文件`config.ini`中指定日志系统当前的输出级别,只有级别不低于指定级别的日志才会被输出(例如在配置文件中指定日志系统当前的输出级别为info,则debug级别的日志在程序实际运行时并不会被输出)。
日志系统有同步和异步两种工作方式,用户也可以在配置文件`config.ini`中指定其工作模式。对于同步模式下的日志系统,当用户调用【日志输出函数】时,程序会同步的将日志打印到控制台上。由于IO是一个比较耗时的操作,频繁的日志IO会导致服务器性能的下降,因此在用户调用【日志输出函数】时,我们先将要打印的日志加到日志队列中,交给一个子线程去IO。
在负责写日志的子线程中,不断的判断日志队列是否为空,如果不为空,则取出日志并输出;如果为空,则使用条件变量阻塞线程(防止线程忙等)。将日志添加到日志队列时,如果发现子线程被阻塞了,则需要唤醒子线程。
注:由于queue是线程不安全的,因此在操作queue时必须加锁,这会导致异步日志系统没法达到应有的性能,下一步的优化方向是使用双缓冲机制实现日志系统(基本思路是,使用两个日志队列A和B,初始时主线程一直向A中写日志,待A写满后,主线程再向B中写日志,此时子线程负责将A中的日志输出。之后主线程再向A中写日志,子线程负责将B中的日志输出,如此循环)。
## 线程池
server使用的线程池是一个轻量级的简易线程池。线程池的主要意义在于直接利用提前构建好的子线程(子线程的数量一般和CPU总核心数相同或接近)处理任务,避免线程频繁创建和销毁的开销。线程池和日志系统一样,采用了单例模式实现。线程池在析构时需要将目前任务队列中的所有任务取出并执行。
在初始化线程池时,就需要根据配置文件`config.ini`中指定的线程数量将子线程预先创建好。由于queue是线程不安全的,因此在操作任务队列时必须要加锁。和日志系统不同的是,任务task的执行时间可能很长,有些任务甚至是无限循环,如果不释放掉之前加的锁,就会导致死锁的产生(例如一个工作线程获取锁后执行一个死循环任务,由于该线程没有释放锁,导致其他的工作线程都阻塞在锁的获取上,从而无法从任务队列中取出任务并执行)。又考虑到加锁的目的仅是为了保证操作任务队列时的线程安全,因此将任务取出队列后,就可以先解锁再执行任务,待任务执行完成后,再重新加锁。代码如下:
```c++
std::unique_lock<std::mutex> lock(ThreadPool::instance()->poolLock);
if(!ThreadPool::instance()->taskQue.empty()){
// 从任务队列中取出任务并执行
auto task=ThreadPool::instance()->taskQue.front();
ThreadPool::instance()->taskQue.pop();
lock.unlock(); // 暂时解锁
task();
lock.lock(); // 重新加锁
}else ThreadPool::instance()->condvar.wait(lock); // 如果任务队列为空,则该线程阻塞
```
主线程使用`addTask`函数向任务队列中添加任务,由于queue是线程不安全的,因此在添加任务时必须先加锁。主线程中可以使用`std::bind`将可调用对象及参数封装成一个`function`对象传给`addTask`函数。
注:线程池进一步优化的方向是:使用合理的线程轮转算法,让各个线程的负载尽量相差不大,避免某个或某些线程过载。
对于C++ 11 而言,使用多线程需要包含头文件`#include <thread>`,并且在链接时需要用到`pthread`库。
## 自增长缓冲区
server使用一个简易的自增长缓冲区。缓冲区分为三个部分:`0~readPos:暂时没有被使用的空间`、`readPos~writePos:可以读的空间(可以把这部分数据读到文件中)`、`writePos~buffer.size:可以写的空间(可以将文件中的数据写到这部分空间中)`。
缓冲区对外提供了五个操作函数:`readFromFile`函数用于从文件中读数据到写空间、`writeToFile`函数用于从读空间向文件中写数据、`appendData`函数用于向可写空间中追加数据、`getData`函数用于取出可读空间中的数据、`readData`用于查看可读空间中的数据。
`writeToFile`的实现较为简单,直接将缓冲区读空间中的可读字节写到文件中即可;`readFromFile`函数的实现则较为复杂,首先我们创建一个足够大的临时缓冲区,并利用分散读将文件中的数据读到Buffer和临时缓冲区中。如果从文件中读出的数据较少,少于Buffer当前可用的字节数,则Buffer无需扩容;否则需要将Buffer扩容。其余函数的实现原理类似。
## 数据库连接池
server使用一个轻量级的简易数据库连接池。数据库连接池的主要作用在于:提前创建好一定量的数据库连接,需要进行数据库操作时,就从连接池中取出一个连接并使用,使用完毕后放回到连接池中(连接池采用的数据结构是队列),避免了频繁创建和销毁连接带来的开销。数据库连接池也是通过单例模式实现的。数据库连接池析构时要关闭所有的数据库连接,释放资源。
对于C++而言,连接MySQL需要先安装MySQL及其开发环境,还需要包含头文件`#include <mysql/mysql.g>`,并且在链接时需要用到`mysqlclient`库。`mysql.h`可以在目录`usr/include/mysql`中找到;相关的库文件可以在`usr/lib/x86_64-linux_gun`中找到。(除了MySQL客户端和服务器外,还需要另外安装MySQL开发工具)
项目中的MySQL文件夹包含C++连接MySQL所需的头文件和库文件。
当到达一个HTTP请求时,服务器开启一个子线程来处理这个HTTP请求。为了简化开发,本项目中使用Python脚本来进行业务层的开发,因此子线程需要调用Python代码来处理这一请求。由于在业务中可能需要和数据库交互,因此在开始处理一个请求时,子线程会从MySQL连接池中取出一个连接(如果MySQL连接池繁忙,则阻塞到能取出一个连接为止),并将该连接传递给Python脚本,之后在Python脚本中可以使用该连接与数据库交互。由于无论是32位系统还是64位系统,long类型和指针类型有相同的长度,因此可以使用long类型的数据来传递指针数据,MySQL连接的传递正是这一原理。
## 定时器
server使用的是一个基于小根堆的定时器,定时器中每个节点保存了该节点的id,到期时间,到期时的回调函数。小根堆的堆顶是到期时间最近的节点。小根堆底层使用vector实现,并且使用了一个map记录节点的id到节点在vector中索引的映射,方便根据节点id快速确定节点的位置。由于小根堆底层是使用vector实现的,因此需要自行实现小根堆中节点位置的调整,以及取出小根堆堆顶的代码。
定时器总共提供了四个函数可供外部程序调用:更新一个结点的到期时间、添加一个结点、获取距离最近的到期时间的毫秒数、根据id删除一个制定的节点。
## Pyth
没有合适的资源?快使用搜索试试~ 我知道了~
基于C++和Python的后端服务器框架项目源码+项目文档,核心服务器是基于C++的,业务层逻辑使用Python脚本编写
共426个文件
hpp:219个
h:160个
cpp:13个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 32 浏览量
2023-10-12
16:06:31
上传
评论
收藏 21.18MB ZIP 举报
温馨提示
本项目是一个基于C++, Python, Linux, MySQL的后端服务器框架。该项目已经开发好的部分包括:核心服务器(基于C++)、MySQL函数库(基于C++)、Python接口层(与C++代码进行对接,方便Python业务层快速开发)。用户只需要使用Python脚本编写业务层逻辑,即可快速搭建一个简易的后端服务器。 项目启动 将编译后生成的可执行文件server,服务器配置文件config.ini放在同一个文件夹下。在同级目录下创建script文件夹,将pmysql、prouter、pscript模块,以及C++ MySQL函数库文件mysqllib.so都放到该文件夹下。然后在终端中输入./server即可启动服务器。
资源推荐
资源详情
资源评论
收起资源包目录
基于C++和Python的后端服务器框架项目源码+项目文档,核心服务器是基于C++的,业务层逻辑使用Python脚本编写 (426个子文件)
libpython3.8.so.1.0 18.9MB
libboost_python38.so.1.71.0 254KB
libmysqlclient.so.21 25B
libmysqlclient.so.21.2.33 7.26MB
libpython3.8.a 47.77MB
libmysqlclient.a 9.33MB
libboost_python38.a 685KB
Server.cpp 11KB
HttpProcess.cpp 10KB
Timer.cpp 4KB
Buffer.cpp 3KB
Log.cpp 3KB
MySQLPool.cpp 2KB
RunPython.cpp 2KB
Epoll.cpp 2KB
mysqllib.cpp 2KB
ThreadPool.cpp 2KB
Connection.cpp 1KB
client.cpp 993B
main.cpp 515B
.gitignore 173B
mysqld_error.h 255KB
pyconfig.h 46KB
unicodeobject.h 45KB
mysql_com.h 36KB
unicodeobject.h 35KB
mysql.h 33KB
abstract.h 30KB
pyport.h 30KB
object.h 29KB
Python-ast.h 26KB
dynamic_annotations.h 22KB
pycore_atomic.h 17KB
initconfig.h 16KB
object.h 15KB
pyerrors.h 12KB
abstract.h 12KB
objimpl.h 10KB
pystate.h 10KB
modsupport.h 9KB
pycore_pystate.h 9KB
longobject.h 9KB
datetime.h 9KB
pytime.h 9KB
bytesobject.h 8KB
ceval.h 8KB
client_plugin.h 8KB
pymath.h 8KB
pycore_pymem.h 8KB
pythonrun.h 7KB
mysqlx_ername.h 7KB
code.h 7KB
plugin_auth_common.h 7KB
codecs.h 7KB
errmsg.h 6KB
pythread.h 6KB
pymem.h 5KB
symtable.h 5KB
pycore_initconfig.h 5KB
opcode.h 5KB
import.h 5KB
floatobject.h 5KB
pyerrors.h 5KB
pystate.h 5KB
my_command.h 4KB
methodobject.h 4KB
fileutils.h 4KB
funcobject.h 4KB
pyhash.h 4KB
mysqlx_error.h 4KB
dictobject.h 4KB
udf_registration_types.h 4KB
longintrepr.h 4KB
pymacro.h 4KB
pycore_pylifecycle.h 4KB
genobject.h 4KB
dictobject.h 4KB
my_compress.h 4KB
Python.h 4KB
objimpl.h 4KB
compile.h 3KB
mysql_time.h 3KB
pymem.h 3KB
setobject.h 3KB
frameobject.h 3KB
bytes_methods.h 3KB
pycore_hamt.h 3KB
pycore_traceback.h 3KB
field_types.h 3KB
descrobject.h 3KB
pymacconfig.h 3KB
parsetok.h 3KB
listobject.h 3KB
pycore_object.h 3KB
weakrefobject.h 3KB
pycore_condvar.h 3KB
memoryobject.h 3KB
pyarena.h 3KB
RunPython.h 3KB
sliceobject.h 2KB
共 426 条
- 1
- 2
- 3
- 4
- 5
资源评论
云哲-吉吉2021
- 粉丝: 3198
- 资源: 1130
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 农村信用社联合社计算机信息系统投产与变更管理办.docx
- 农村信用社联合社计算机信息系统数据管理办法.docx
- 利用SPSS作临床效度分析线上计算网站介绍-医学研究部统计谘.(医学PPT课件).ppt
- 利用Zabbix监控mysqldump定时备份数据库状态.docx
- 利用计算机解决问题的基本过程.doc
- 化工铁路通信工程总结.doc
- 北京大学网络教育软件工程作业.docx
- 医药公司(连锁店)计算机操作规程未新系统的自行按照旧制修改-新系统过制的编号加修模版.doc
- 医药公司(连锁店)计算机系统操作规程模版.doc
- 医药连锁门店计算机系统的操作和管理程序未新系统的自行按照旧制修改-新系统过制的编号加修模版.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功