高并发内存池--C++项目实践
项目介绍简介这是一款高并发的C++内存管理项目,原型是google的一个开源项目tcmalloc,全称Thread_Caching Malloc,即线程缓存的malloc,tcmalloc实现了高效的多线程内存管理,可以用于替代系统的内存分配的相关的函数malloc,new,free,delete等
实际上原型项目内容很多,但本着渐进学习的理念,我们可以先把tcmalloc最核心的框架简化,模拟实现出一个自己的高并发内存池。在掌握了其中的精华的设计思想和编程技巧后,我们可以再进一步实现或改造原本的tcmalloc项目,或者将学习成果用于其它项目或者更多用途
应用背景tcmalloc是一项十分常用的技术,很多对性能要求较高的场景都能用到它
高性能服务器
TCMalloc被广泛应用于高并发的服务器程序中,如Web服务器和数据库服务器。这些场景下,需要快速分配和释放内存,TCMalloc通过线程缓存机制减少了锁的竞争,提升了性能。
游戏开发
游戏引擎通常需要频繁分配和释放内存,尤其是在运行时动态创建和销毁对象。TCMalloc的低延迟和高吞吐量使其成为游戏开发的理想选择。
大数据处 ...
设计模式的C++实现(5)——原型模式
模式名称: 原型模式-Prototype类型: 创建型模式问题-使用场景: 当创建不同对象的过程过于复杂,或者需要隐藏/封装创建对象的具体过程,或者组织项目需要创建过多的子类,类的数目需要优化减少时解决方案: 用原型实例指定创建对象的种类,并通过拷贝这些原型来创建新的对象效果: 相比其它模式,用户只需考虑怎么检索到所需要的原型对象来拷贝出新的对象给自己用,而不用考虑如何构造。这样的设计能简化用户操作,且能极大地增加扩展性。
Python特殊函数设计
MapReducefilteriteryield
【补丁更新v1.2】同步&异步⽇志系统的问题优化与异常处理
解决异步日志器黏包问题由于原本的设计是一股脑直接把日志信息送进了缓冲区,导致输出的时候会产生黏包问题。但是为什么一开始没在意呢?因为标准输出和文件输出都不在意黏包问题,同时输出多条日志是没问题的。
但是!一旦要开始插入数据库,问题就很严重了。日志信息必须一行一行储存。原本的黏包问题会导致日志信息的解析不可解,所以我们需要修改原本的代码使其能够解决黏包问题
分隔符用特定的分隔符标记一次日志的头尾是最容易想到的解决方案。
然而日志信息是字符串,任何字符都有可能出现,导致找不到特定的分隔符可以安全地分隔日志信息
分隔符只适用于待封装信息的字符在限定范围内时使用。
封装报头假如我们能获得一段日志的长度就好了。
这样的愿望可以封装报头实现。在获取一长段数据时,我们规定最前面的是报头,包含第一段报文的信息(在这个项目里只简单的包括长度信息)。这样我们就能先读取信息再读取报文了。
那么怎么标定报头的范围呢?
约定使用定长报头
约定使用分隔符
定长报头很好理解,而这里又能用分隔符了是因为报头在一段信息的最前面,最先遇到的特殊字符必定是作为分隔符存在的
这里因为没太多信息需要封装进报头,所以我们采 ...
C++连接MySQL常见接口/类介绍
MySQL准备为了便于测试,我们专门创建一个用于测试的用户和数据库,并给予相关权限
12345create user 'conn'@'localhost' identified by '12345678';create database testDB;grant all privileges on testDB.* to 'conn'@'localhost';
认识接口/类我们将逐个介绍如下类及其相关接口
sql::SQLString
sql::mysql::MySQL_Driver –<mysql_driver.h>
sql::mysql::get_mysql_driver_instance()
sql::Connection –<mysql_connection.h>
sql::Statement –<cppconn/statement.h>
sql::ResultSet –<cppconn/result ...
MySQL用户管理
为什么有用户管理类比Linux中只有root用户过于危险,因为root能随意地增删查改计算机上的任意文件
MySQL只有root用户登录也是十分危险的,因为root有增删查改所有数据库和表的权限,数据安全得不到保障,所以MySQL有自己的用户管理系统
用户管理的使用用户信息显然用户信息是需要组织和管理的,所以按照先描述,再组织的原则,我们来思考一下用户信息在逻辑上是什么样的管理思路
描述用户只需略微思考一下在MySQL中描述一个对象怎么样最方便准确,很明显,就是它自带的表结构。
实际上也确实是这样,MySQL用了一个在mysql数据库中的user表用来描述所有的用户
client1234567891011121314151617181920212223242526272829mysql> use mysqlDatabase changedmysql> select host,user,authentication_string from user;+-----------+------------------+-------------------------------- ...
设计模式的C++实现(4)——迭代器Iterator
模式名称: 迭代器-Iterator类型: 行为模式问题-使用场景: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示解决方案: 将对列表(对象集合)的访问和遍历从具体对象中分离出来,并放入一个迭代器对象中,由它负责实现访问和遍历功能效果: 提供了统一的遍历成员的方法,降低了用户的使用难度,提高了代码的封装性和可扩展性。代价是增加了代码复杂性,增加了更多的类,提高了代码的设计难度
注:本文的迭代器风格更偏向STL库中的迭代器,而不是《设计模式》中的抽象迭代器
灵感来源:某种意义上将,Iterator要做的事就是模仿数组中的指针,指针可以前后移动,方便地遍历数组,还可以用指针访问数组元素。我们希望把这种指针特性也用在其它数据结构上(特指组织管理多个对象的聚合体),但可惜的是原生指针的这种方便依赖于数组的地址是连续的。因此为了实现遍历和访问功能,我们需要把这些功能封装在Iterator类中,让它实例化出的对象来行使数组指针一样的行为。
类层次设计我们先来设计一个抽象迭代器类来规定迭代器应有哪些行为:
12345678910111213141516171819 ...
设计模式的C++实现(0)——初识设计模式
《设计模式的C++实现》为作者对系列博客的又一次尝试:在开发过C++基于多设计模式下的同步&异步⽇志系统🔗后,作者接触到了《设计模式》这本书,颇有感触,于是决定写博客来记录读后的灵感,然而随着博客内容的不断丰富,单篇的博客已经承载不下如此多样的内容,各种各样的设计模式便是一个典例,所以我决定将设计模式相关的博客拆成一个系列博客
目录:TODO
知识基础本系列博客着重于经典设计模式的介绍和运用C++类和对象技术将其实现,所以要求读者已经能够熟练掌握C++类和对象技术。并且当我们提及抽象类,多态,或者继承,虚函数的声明与实现等概念时,你应当已经对这些概念了然于心,而不是一知半解,还要查资料复习
设计模式从何而来设计模式描述了在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。设计模式捕获了随时间进化与发展的问题的求解方法,因此它们往往并不是人们从一开始就采用的设计方案,它们反映了不为人知的重新设计和重新编码的成果,而这些都来自软件开发者为了设计出灵活可复用的软件而长时间进行的艰苦努力。设计模式所做的事,就是捕获这些解决方案,并用简洁易用的方式表达出来。
学习目标设 ...
【代码整理】同步&异步⽇志系统的代码复盘
在项目的介绍博客🔗中,我们着重于代码功能的实现,而对项目代码整体的结构和风格欠缺重视,使其可读性有所欠缺,代码规范性也有所不足。所以在这篇博客中,我们将按上篇博客编写代码的顺序,再一次回顾写好的代码,并着重于:
调整代码结构
增加必要注释,删除冗余注释
添加必要的小括号,突出优先级
将代码的简便写法改写回易读的写法
实用类
增加功能简介
增加注释
增加空行12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576#pragma once#include <iostream>#include <fstream>#include <sstream>#include <string>#include <ctime>#include <cassert>#include <sys/stat ...
初识Linux套接字(socket)和TCP/UDP协议
这是系列博客中的第二篇,导航如下
初识计算机网络🔗
初识Linux套接字(socket)和TCP/UDP协议🔗 👈您在这里
在Linux环境中,套接字(Socket)是一种用于进程间通信(IPC)的机制,但这里的进程,包括了同一网络下其它主机的进程,所以它被广泛应用于网络编程。它允许不同计算机上的进程或同一计算机上的不同进程之间进行数据交换。
由于此时我们的网络编程基础较少,所以本文的内容更偏向于实践,而不是原理。希望能在动手实践中加深对网络编程的熟悉程度,减少陌生感
在本文中,我们将:
知识铺垫:认识IP地址, 端口号, 网络字节序等网络编程中的基本概念(简略)
socket API学习
实现一个简单的UPD客户端/服务器
实现一个简单的TCP客户端/服务器(服务器包括单连接版本,多进程版本,多线程版本)
知识铺垫理解源IP地址和目的IP地址在数据包的头部中,包含两个IP地址,分别叫做源IP地址和目的IP地址
为什么要有两个IP地址?因为一般通过网络建立的通信都是双向的,而且一方接收请求后,一般还要把响应发送回去,所以含有两个IP地址才 ...