当前位置: 首页 > news >正文

Leaky singletons的一种使用场景

Leaky singletons的一种使用场景

文章目录

  • Leaky singletons的一种使用场景
    • 场景
    • 问题本质
    • 如何解决
    • Leaky singletons

场景

最近遇到了这个问题,正好想记录下。
比如你有一段代码,如下(伪代码):

static std::map<int, std::string> g_test_map;class Test {public:~Test() {}  // 析构里对线程做join动作bool Init() {} // 启动多个线程对g_test_map进行读写操作
};

你在一个文件中定义了一个static map静态变量,并且你的代码被编译成test.so。
重点来了,这个test.so是以共享库的形式被别人使用,而且是通过dlopen、dlclose的形式加载和卸载你的test.so。

使用方代码如下(伪代码):

std::shared_ptr<Test> LoadTest() {dlopen("./test.so");std::shared_ptr<Test> test = std::make_shared<Test>();test->Init();return test;
}UnLoadTest() {test.reset();dlclose("./test.so");
}

使用方1在dlopen你的test.so的时候,会申请出这个static map的内存空间,你的test.so中会另外启动多个线程在对这个map进行读写操作。并且会将Test的shared_ptr返回给使用方2持有。

这里就会形成如下关系图:
使用方2->(load) 使用方1的.so -> 使用方1 (dlopen) test.so。

那在使用方2 退出的时候,使用方1会先reset 它保存的test的shared_ptr,然后再dlclose。

这里就会出现问题:

  1. 使用方1在reset test的时候,只是会将test的引用技术减1,此时使用方2还持有着test,所以test并不会析构,也不会触发线程join;
  2. 紧接着使用方1开始 dlclose,并且dlclose的时候会将g_test_map析构掉;
  3. 此时由于test还未析构,所以test中的线程还在run,这个时候就会出现访问已析构的内存,产生coredump。

这个问题如果用asan跑下,可以很明显看出asan提示的

AddressSanitizer: heap-use-after-free on address
READ of size 8 at  0xffff8e408f90 thread T9:0xffff8e408f90 freed by thread T0 here:

这段的意思就是堆内存释放后又被使用,0xffff8e408f90 这个地址在T0被释放,又在T9被使用。

问题本质

所以综上所述,这个问题的本质是dlclose的时候静态全局变量被析构,但是存在running的线程还在使用这块全局内存。

这里有人会说,那dlclose的时候应该将test清理干净,这样就不会存在这种场景。这种说法没问题,但是这里Test的线程是在Test析构的时候join的,而Test是以shared_ptr的形式返回,并且又被使用方2持有着。所以这里场景下使用方1本质控制不了test的析构。

如何解决

  1. 第一种方法可以将static map封装成类,然后用shared_ptr包装起来,别的线程要读写这个map,就必须保存一份map的shared_ptr类,这样就能保存最后释放。
  2. 第二种方法也是之前遇到glog0.4中的一个问题,参考glog的修复手段。
    glog中的问题也是进程退出的时候static mutex被释放了,但是别的线程还在使用这个mutex,可以看下这个:
    glog0.4.0版本存在此问题,static google::log_mutex destroyed on exit, while other still existing threads want to log。具体可看如下链接:
https://github.com/google/glog/issues/504

glog里使用了Leaky singletons这种方式解决了此问题。

Leaky singletons

Leaky singletons很好理解,翻译成中文就是泄漏式单例,代码如下:

static Singleton& instance() {/** 以前的实现static Singleton inst;return inst;*/static Singleton* inst = new Singleton; // 返回指针而不是整个对象return *inst;
}

用静态指针替换了静态对象,这样进程启动只会new一份,并且不会手动释放,而是进程退出的时候被系统回收内存。

这里并不是真实泄露,最终内存也会随着进程退出被系统回收。

相关文章:

Leaky singletons的一种使用场景

Leaky singletons的一种使用场景 文章目录 Leaky singletons的一种使用场景场景问题本质如何解决Leaky singletons 场景 最近遇到了这个问题&#xff0c;正好想记录下。 比如你有一段代码&#xff0c;如下&#xff08;伪代码&#xff09;&#xff1a; static std::map<int…...

TensorFlow图像多标签分类实例

接下来&#xff0c;我们将从零开始讲解一个基于TensorFlow的图像多标签分类实例&#xff0c;这里以图片验证码为例进行讲解。 在我们访问某个网站的时候&#xff0c;经常会遇到图片验证码。图片验证码的主要目的是区分爬虫程序和人类&#xff0c;并将爬虫程序阻挡在外。 下面…...

Python程序设计期末复习笔记

文章目录 一、数据存储1.1 倒计时1.2 os库1.3 字符串操作1.4 文件操作1.5 列表操作1.6 元组1.7 字典 二、文本处理及可视化2.1 jieba分词2.2 集合操作2.3 pdf文件读取2.4 参数传递2.5 变量作用域 三、数据处理分析3.1 Sumpy3.2 Matplotlib3.3 Numpy 四、Pandas4.1 索引操作4.2 …...

人大与加拿大女王大学金融硕士—与您共创辉煌

生活的本质就是有意识的活着&#xff0c;而生活的智慧就是活出了自己想要的样子&#xff0c;那些真正厉害的人&#xff0c;从来都在默默努力&#xff0c;伴随着金融人才的需求日益增长&#xff0c;中国人民大学与加拿大女王大学联合推出了人大女王金融硕士项目&#xff0c;旨在…...

Generalized Zero-Shot Learning With Multi-Channel Gaussian Mixture VAE

L D A _{DA} DA​最大化编码后两种特征分布之间的相似性 辅助信息 作者未提供代码...

10.30 知识总结(标签分类、css介绍等)

一、 标签的分类 1.1 单标签 img br hr <img /> 1.2 双标签 a h p div <a></a> 1.3 按照标签属性分类 1.3.1 块儿标签 即自己独自占一行 h1-h6 p div 1.3.2 行内(内联)标签 即自身文本有多大就占多大 a span u i b s 二、 标签的嵌套 标签之间是可以互相…...

DoLa:对比层解码提高大型语言模型的事实性

DoLa&#xff1a;对比层解码提高大型语言模型的事实性 摘要1 引言2 方法2.1 事实知识在不同层级上演化2.2 动态早期层选择2.3 预测对比 3 实验3.1 任务3.2 实验设置3.3 多项选择3.3.1 TruthfulQA&#xff1a;多项选择3.3.2 FACTOR&#xff1a;维基、新闻 3.4 开放式文本生成3.4…...

解决由于找不到mfc140u.dll无法继续执行此代码问题的4个方法

mfc140u.dll是Microsoft Foundation Class&#xff08;微软基础类库&#xff09;中的一个动态链接库文件&#xff0c;它包含了许多用于实现Windows应用程序的基本功能。当我们在编写或运行基于MFC的程序时&#xff0c;如果系统中缺少这个文件&#xff0c;就会出现“找不到mfc14…...

MySQL高性能优化规范建议

当涉及到MySQL数据库的性能优化时&#xff0c;有许多方面需要考虑。以下是一些通用的MySQL性能优化规范建议&#xff1a; 合适的索引&#xff1a; 确保表中的字段使用了适当的索引。这能大幅提升检索速度。但避免过多索引&#xff0c;因为它会增加写操作的成本。 优化查询语句…...

pytorch 入门 (五)案例三:乳腺癌识别-VGG16实现

本文为&#x1f517;小白入门Pytorch内部限免文章 &#x1f368; 本文为&#x1f517;小白入门Pytorch中的学习记录博客&#x1f366; 参考文章&#xff1a;【小白入门Pytorch】乳腺癌识别&#x1f356; 原作者&#xff1a;K同学啊 在本案例中&#xff0c;我将带大家探索一下深…...

vue中electron与vue通信(fs.existsSync is not a function解决方案)

electron向vue发送消息 dist/main.js (整个文件配置在另一条博客里) win new BrowserWindow({width:1920,height:1080,webPreferences: {// 是否启用Node integrationnodeIntegration: true, // Electron 5.0.0 版本之后它将被默认false// 是否在独立 JavaScript 环境中运行…...

LSTM-Based Anomaly Detection of Process Instances Benchmark and Tweaks翻译

论文《LSTM-Based Anomaly Detection of Process Instances Benchmark and Tweaks》翻译 LSTM-Based Anomaly Detection of Process Instances Benchmark and Tweaks翻译...

文件类漏洞总结, 文件包含, 文件上传, 文件下载

文件类漏洞总结 一, 文件包含 1. 文件包含绕过 实际环境中不是都是像$_GET[file]; incude $file 这样直接把变量传入包含函数的。 在很多时候包含的变量文件不是完全可控的&#xff0c;比如下面这段代码指定了前缀和后缀: <?php $file S_GET[filename]; include /opt/…...

SpringBoot篇---第四篇

系列文章目录 文章目录 系列文章目录一、springboot常用的starter有哪些二、 SpringBoot 实现热部署有哪几种方式&#xff1f;三、如何理解 Spring Boot 配置加载顺序&#xff1f; 一、springboot常用的starter有哪些 spring-boot-starter-web 嵌入tomcat和web开发需要servlet…...

Knife4j使用教程(一) -- 在不同版本SpringBoot,选用不同的Knife4j相关的jar包

目录 1. Knife4j的项目背景 2. Knife4j的选择 2.1 选用 Spring Boot 版本在 2.4.0~3.0.0之间 2.2 选用 Spring Boot 版本在 3.0.0之上...

Octave Convolution学习笔记 (附代码)

论文地址&#xff1a;https://export.arxiv.org/pdf/1904.05049 代码地址&#xff1a;https://gitcode.com/mirrors/lxtgh/octaveconv_pytorch/overview?utm_sourcecsdn_github_accelerator 1.是什么&#xff1f; OctaveNet网络属于paper《Drop an Octave: Reducing Spatia…...

SpringSecurity 认证实战

一. 项目数据准备 1.1 添加依赖 <dependencies><!--spring security--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!--web起步依赖-…...

echarts中横向柱状图的数字在条纹上方

实现效果&#xff1a; 数字在条纹的上方 实现方法&#xff1a;这些数字是用新添加一个坐标轴来实现的 直接添加坐标轴数字显示是在条纹的正右边 所以需要配置一下偏移 完整代码 var option {grid: {left: "3%",right: "4%",bottom: "3%",cont…...

【仙逆】尸阴宗始祖现身,王林修得黄泉生窍诀,阿呆惊险逃生

【侵权联系删除】【文/郑尔巴金】 深度爆料最新集&#xff0c;王林终于成功筑基&#xff0c;这一集的《仙逆》动漫真是让人热血沸腾啊&#xff01;在这个阶段&#xff0c;王林展现出了他的决心和毅力&#xff0c;成功地击杀了藤厉&#xff0c;并采取了夺基大法&#xff0c;从藤…...

C++二叉树剪枝

文章目录 C二叉树剪枝题目链接题目描述解题思路代码复杂度分析 C二叉树剪枝 题目链接 LCR 047. 二叉树剪枝 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个二叉树 根节点 root &#xff0c;树的每个节点的值要么是 0&#xff0c;要么是 1。请剪除该二叉树中所有节…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...