一步一步写线程之十一线程池应用内存池

一、内存池

内存池,非常好理解,就是存储内存的一个池子(Pool),一般来说,都是使用各种容器或者自己实现的类似容器的内存管理类。内存池其实就是为了解决两个主要问题,一个是内存反复分配回收的性能问题;另外一个就是小内存的反复分配导致的内存碎片问题。一般来说,内存池的管理以固定大小为宜(不固定也无所谓,但普适性可能就很差)。
使用内存池是有一些前提要求的,第一是要内存需要反复不断分配(高频);第二,内存分配大小存在一定的特征(比如大小有一个可控的限制);第三,内存分配要尽量快;第四,内存不可共用;第五,内存分配成功率高。
内存池的缺点也显而易见,第一就是增加了开发的复杂性;第二,浪费内存资源(这就看设计得的取舍);第三,简单内存应用不能使用;第四,无法处理大内存(特别是上百兆以后),这也是开源框架中,一般大内存都直接使用原始接口。
说明:对象池本质也是内存的管理,所以此处把二者简单的混为一谈。

二、内存池在线程池中的应用

在线程中,对内存的分配的要求,几乎都占全了。所以在一些大的涉及到内存管理的线程池中,一般都会有一个内存池作为辅助来处理数据的内存分配和管理。最典型的例子仍然是Web服务端,一个HTTP请求过来,都会有一个数据包,这个数据包的解析就需要内存分析回收,为了快捷和防止内存碎片一般会使用一个内存池来进行管理。而Web服务端一般是多线程(多进程)的,但用不用线程(进程)池,就不敢一概而论了。
而且,既然用到了线程池,说明程序还是比较复杂的,所以再增加内存池的复杂性,也算不得什么,投入和收益一般来说是合适的。不过在线程池中使用内存池,缺点就是要处理数据的同步(无锁编程以后再分析)。这种并发处理的方法有很多,可以分段串行(包括使用线程本地内存等),可以偷窃也可以使用互斥等等。

三、源码

下面看一个内存池应用在线程池中的例子:

#ifndef __MEMPOOLS_H__
#define __MEMPOOLS_H__#include <memory>
#include <queue>
#include <vector>template <typename T> class MemPools : public NoCopy {
public:MemPools() = default;~MemPools() = default;public:T Get() {std::lock_guard lg(this->mt_);T t = this->vec_.back();this->vec_.pop_back();this->count_--;return t;}void Set(T t) {std::lock_guard lg(this->mt_);this->vec_.emplace_back(t);this->count_++;}std::shared_ptr<T> GetPtr() {std::lock_guard lg(this->mt_);auto pt = this->pvec_.back();this->pvec_.pop_back();this->count_--;return pt;}void SetPtr(std::shared_ptr<T> pt) {std::lock_guard lg(this->mt_);this->pvec_.emplace_back(pt);this->count_++;}size_t GetMemPoolsLen() const { return this->count_; }void Clear() { this->vec_.clear(); }bool Extend(int count = 100, int flag = 0) { return this->createMemPools(count, flag); }private:bool initMemPools(int count = 1000, int flag = 0) {bool ret = true;ret = this->createMemPools(count, 0);return ret;}bool createMemPools(const int count, int flag) {bool ret = true;for (int num = 0; num < count; num++) {if (0 == flag) {T t;std::lock_guard lg(this->mt_);this->vec_.emplace_back(t);} else if (1 == flag) {std::shared_ptr<T> pt = std::make_shared<T>();std::lock_guard lg(this->mt_);this->pvec_.emplace_back(pt);}}this->count_ += count;return ret;}private:std::vector<T> vec_;std::vector<std::shared_ptr<T>> pvec_;size_t count_ = 0;std::mutex mt_;
};#endif // __MEMPOOLS_H__

是不是发现内存池和任务管理的模板类有些相似?确实。但二者其实有着本质的不同。前者需要动态适应不同的容器并且一般不会自己主动分配内存对象,而内存池一般只需要有一种内存管理容器即可,同时必须提前创建一系列的相关内存对象(所以有的也叫对象池)。代码的应用也很简单,直接将原来的分配回收内存的地方改成这里的Get和Set相关即可。上面的代码有一点小瑕疵,直接返回了对象,其实返回对象的引用或者直接使用指针其实是最好的。
掌握方法,踏入门槛,这是学习的最基本的形式。这就和打仗一样,集中优势兵力,突破一点,然后再全线展开。

四、总结

可能有的同学说这个和在网上或者书上看到的内存池不大一样啊?其实本质是一样的。直接分配内存控制比特流,然后再分块拆分和上面的直接进行对象分配本质是相同的,不同的在于可能直接使用比特流会更灵活。或者说把本文叫做对象池,可能就更容易理解了。
这一篇只是针对线程池中的内存池应用进行一个基础的分析说明,后面会抽时间对内存池有一个全面的分析说明。诸如内存池的大小分组(微型、小型、中型、大型)和是否连续处置(内存一次分配,分块使用)等,本文都没有涉及,目的只是一个很简单的在线程池中使用内存池,知其所以然即可。细节需要自己不断的深入研究和学习,掌握后按照这样的接口使用即可。
学以致用,才是根本。

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

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

相关文章

关于“泼辣”DB 你应该知道的几件事

PolarDB PolarDB for PostgreSQL&#xff08;以下简称 PolarDB&#xff09;是一款阿里云自主研发的企业级数据库产品&#xff0c;采用计算存储分离架构&#xff0c;100% 兼容 PostgreSQL。 PolarDB 的存储与计算能力均可横向扩展&#xff0c;具有高可靠、高可用、弹性扩展等企…

文件(夹)批量重命名数字、字母、日期、中文数字大写小写

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 目标是重命名下面5个文件&#xff08;也可以是文件夹等&#xff0c;任意&#xff09;&#xff0c;从大写中文数字“贰”开始 打开工具&#xff0c;找到“文…

使用机器学习确定文本的编程语言

导入必要的库 norman Python 语句&#xff1a;import <span style"color:#000000"><span style"background-color:#fbedbb"><span style"color:#0000ff">import</span> pandas <span style"color:#0000ff&quo…

Java面试题:解释Java内存模型(JMM)是什么,它为何重要?

Java内存模型&#xff08;Java Memory Model, JMM&#xff09; 定义&#xff1a; Java内存模型是一个抽象的概念&#xff0c;它定义了Java程序中各种变量&#xff08;线程共享变量&#xff09;的访问规则&#xff0c;以及在并发环境下&#xff0c;这些变量的读写操作如何与内存…

基于OpenCv的图像Harris角点检测

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

使用D3.js进行数据可视化

D3.js介绍 D3.js是一个流行的JavaScript数据可视化库&#xff0c;全称为Data-Driven Documents&#xff0c;即数据驱动文档。它以数据为核心&#xff0c;通过数据来驱动文档的展示和操作。D3.js提供了丰富的API和工具&#xff0c;使得开发者能够创建出各种交互式和动态的数据可…

无界微前端项目实战

前言 微前端框架&#xff1a;无界 wujievue 微前端是什么 | 无界主应用&#xff1a;Vue 2 elementui子应用&#xff1a;Vue 3viteelement plus 前提 子应用的资源和接口的请求都在主域名发起&#xff0c;所以会有跨域问题&#xff0c;子应用必须做cors 设置vue3vite 项目跨…

爬取B站评论:Python技术实现详解

引言 在当今信息爆炸的互联网时代&#xff0c;用户生成的内容不断涌现&#xff0c;其中包括了各种各样的评论。而B站作为一个充满活力的视频分享平台&#xff0c;其评论区更是一个充满了各种各样精彩评论的宝藏地。那么&#xff0c;有没有一种简单的方法可以将这些评论收集起来…

大模型日报2024-05-03

大模型日报 2024-05-03 大模型资讯 马克扎克伯格宣布Meta发布Llama 3大型语言模型的重大AI新闻 摘要: Meta公司在周四发布了其Llama 3大型语言模型的首两个版本。该模型是Meta AI的动力核心&#xff0c;马克扎克伯格称其为“未来的...”。这一进展标志着Meta在人工智能领域的进…

深度学习心得

1. KL loss 其经常要与softmax一起使用&#xff0c;就是为了学习one-hot分布 2. 降维 Pooling层的作用是增加模型的鲁棒性&#xff0c;让模型对输入的少量变化不那么敏感。 如果真想通过降维&#xff0c;减少模型训练参数&#xff0c;那应该用PCA降维方法&#xff0c; skl…

Java中new一个对象内存区域如何变化?顺序是什么?

Java中new一个对象内存区域如何变化&#xff1f;顺序是什么&#xff1f; 如果你对Java内存区域了解的话&#xff0c;那么肯定会知道&#xff0c;创建对象如果是第一次的话&#xff0c;首先肯定是要加载对应的Class&#xff08;要创建对象的类&#xff09;,加载的类信息就是放在…

贪心-耍杂技的牛

问题描述 农民约翰的 N头奶牛&#xff08;编号为 1…N&#xff09;计划逃跑并加入马戏团&#xff0c;为此它们决定练习表演杂技。 奶牛们不是非常有创意&#xff0c;只提出了一个杂技表演&#xff1a; 叠罗汉&#xff0c;表演时&#xff0c;奶牛们站在彼此的身上&#xff0c;形…

Django之配置数据库

一&#xff0c;创建项目 二&#xff0c;将项目的setting.py中的 DATABASES {default: {ENGINE: django.db.backends.sqlite3,NAME: BASE_DIR / db.sqlite3,} }替换成如下&#xff08;以mysql为例&#xff09; DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: …

力扣---二叉树的锯齿形层序遍历

给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,…

基于深度学习神经网络的AI图片上色DDcolor系统源码

第一步&#xff1a;DDcolor介绍 DDColor 是最新的 SOTA 图像上色算法&#xff0c;能够对输入的黑白图像生成自然生动的彩色结果&#xff0c;使用 UNet 结构的骨干网络和图像解码器分别实现图像特征提取和特征图上采样&#xff0c;并利用 Transformer 结构的颜色解码器完成基于视…

PDF Shaper Ultimate 免安装中文破姐版 v14.1

软件介绍 PDF Shaper是一套完整的多功能PDF编辑工具&#xff0c;可实现最高的生产力和文档安全性。它允许你分割&#xff0c;合并&#xff0c;水印&#xff0c;署名&#xff0c;优化&#xff0c;转换&#xff0c;加密和解密您的PDF文件&#xff0c;也可插入和移动页&#xff0…

数字化思维的目的与价值,你真的懂吗?

在这个数字时代&#xff0c;数字化思维正逐渐成为企业和个人的能力。那么&#xff0c;数字化思维究竟以什么为中心&#xff1f;为了达成什么目的&#xff1f;又具有怎样的价值呢&#xff1f;让我们一起来揭开这个神秘的面纱。 数字化思维以数据为中心。数据成为了决策的关键依据…

Python系列一之excel的读取

这里我常用的 python 对于 excel 的读取库有两个&#xff0c;一个是 xlsxwriter 用于操作 excel 的写入&#xff0c;一个是 xlrd 用于 excel 文件的读取。 使用的库的版本如下&#xff1a; xlsx1.2.6xlrd1.1.0 xlsxwriter 写入 excel 新建一个 excel import xlsxwriterpat…

C语言实验-学生信息管理系统

按以下菜单界面编写学生信息管理系统&#xff1b; 1&#xff09;录入学生信息首先输入学生人数&#xff0c;然后根据学生人数开辟动态数组&#xff1b; 2&#xff09;学生信息包括学号、姓名、性别、三门课成绩、总分&#xff1b;其中学号、姓名、 性别、三门课成绩是需要从键盘…

初始《stack》《queue》及手搓模拟《stack》《queue》

目录 前言&#xff1a; stack的介绍和使用 stack的介绍&#xff1a; ​编辑stack的使用&#xff1a; ​编辑stack的模拟实现&#xff1a; queue的介绍和使用 queue的介绍&#xff1a; queue的使用: queue的模拟实现: priority_queue的介绍和使用 priority_queue的介绍:…