C++之智能指针shared_ptr死锁问题(二百)

news/2025/1/12 1:04:45/

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:探讨智能指针shared_ptr死锁问题如何解决?

2.应用实例

<1>.shared_ptr死锁

#include <iostream>
#include <memory>
#include <string>
using namespace std;int main(){string *buf = new string("1111");shared_ptr<string> pa(buf);shared_ptr<string> pb(buf);cout << "pa.use_count " << pa.use_count() << endl;cout << "pb.use_count " << pb.use_count() << endl;return 0;
}

使得两个shared_ptr对象托管同一个指针:
tring *buf = new string("1111");
shared_ptr<string> pa(buf);
shared_ptr<string> pb(buf);

  • pa 和 pa 并不会共享同一个对buf的托管计数,而是各自将对buf的托管计数都记为 1(pb无法知道 buf已经被 pa 托管过)。
    当pa消亡时要析构buf,pb消亡时要再次析构buf,这会导致程序崩溃。

<2>.shared_ptr解锁

#include <iostream>
#include <memory>
#include <string>
using namespace std;
int main(){string *buf1 = new string("1111");string *buf2 = new string("2222");shared_ptr<string> pa(buf1);shared_ptr<string> pb(buf2);pa = pb;cout << "pa.use_count " << pa.use_count() << endl;cout << "pb.use_count " << pb.use_count() << endl;return 0;
}

<3>.两个类相互引用对方shared_ptr造成死锁

#include <iostream>
#include <memory>
#include <string>
using namespace std;class Test2;
class Test1{
public:shared_ptr<Test2> pb_;~Test1(){cout << "Test1 delete\n";}
};class Test2{
public:shared_ptr<Test1> pa_;~Test2(){cout << "Test2 delete\n";}
};void test() {//v1.0// shared_ptr<Test2> pb(new Test2());// shared_ptr<Test1> pa(new Test1());// pb->pa_ = pa;// pa->pb_ = pb;//v2.0shared_ptr<Test1> pa = make_shared<Test1>();shared_ptr<Test2> pb = make_shared<Test2>();pb->pa_ = pa;pa->pb_ = pb;//由于share_ptr是共享资源,所以pb所指向的资源的引用计数也会加1cout << "pb.use_count " << pb.use_count() << endl;//2cout << "pa.use_count " << pa.use_count() << endl;//2}//程序结束时,没有调用Test1和Test2的析构函数int main(){test();return 0;
}

<4>.两个类使用weak_ptr解锁

1.weak_ptr是用于解决shared_ptr相互引用时产生死锁问题的智能指针。
2.两个shared_ptr相互引用,这两个shared_ptr指针的引用计数永远不会下降为0,资源永远不会释放。
3.weak_ptr是对对象的一种弱引用,它不会增加对象的use_count,weak_ptr和shared_ptr可以相互转化,
4.shared_ptr可以直接赋值给weak_ptr,weak_ptr也可以通过调用lock函数来获得shared_ptr。
5.将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。
6.指向对象的shared_ptr被销毁、释放。weak_ptr指向对象也会被释放。

#include <iostream>
#include <memory>
#include <string>
using namespace std;class Test2;
class Test1{
public://shared_ptr<Test2> pb_;weak_ptr<Test2> pb_;~Test1(){cout << "Test1 delete\n";}
};class Test2{
public:shared_ptr<Test1> pa_;~Test2(){cout << "Test2 delete\n";}
};void test() {//v1.0// shared_ptr<Test2> pb(new Test2());// shared_ptr<Test1> pa(new Test1());// pb->pa_ = pa;// pa->pb_ = pb;//v2.0shared_ptr<Test1> pa = make_shared<Test1>();shared_ptr<Test2> pb = make_shared<Test2>();pb->pa_ = pa;pa->pb_ = pb;cout << "pb.use_count " << pb.use_count() << endl;//2cout << "pa.use_count " << pa.use_count() << endl;//2}
int main(){test();return 0;
}

将shared_ptr改为weak_ptr弱智能指针。


http://www.ppmy.cn/news/1107860.html

相关文章

Linux下使用libuvc读取控制USB免驱摄像头

一、前言 libuvc是一个开源的库,用于在Linux和其他操作系统上与USB视频设备进行交互。提供了一组函数和接口,使开发人员可以轻松地访问和控制USB摄像头。 libuvc库实现了对UVC(USB Video Class)设备的支持。UVC是一个标准的USB设备类别,用于视频流传输和摄像头控制。通过…

Pyspark综合案例(pyspark安装和java运行环境配置)

一、RDD对象 PySpark支持多种数据的输入&#xff0c;在输入完成后&#xff0c;都会得到一个&#xff1a;RDD类的对象 RDD全称为&#xff1a;弹性分布式数据集&#xff08;Resilient Distributed Datasets&#xff09; PySpark针对数据的处理&#xff0c;都是以RDD对象作为载…

调教 文心一言 生成 AI绘画 提示词(Midjourney)

文章目录 第一步第二步第三步第四步第五步第六步第七步第八步 文心一言支持连续对话 我瞎玩的非专业哈哈 第一步 你好&#xff0c;今天我们要用扩散模型创建图像。我会给你提供一些信息。行吗? 第二步 这是Midjourney的工作原理:Midjourney是另一个基于ai的工具&#xff0c;能…

Ubuntu 安装redis数据库,并设置开机自启动

1、下载安装包 wget http://download.redis.io/releases/redis-7.0.9.tar.gz 2、解压 tar -zxvf redis-7.0.9.tar.gz 3、复制到解压缩的包移动到/usr/local/ sudo mv ./redis-7.0.9 /usr/local/ 4、编译 cd /usr/local/redis-7.0.9 sudo make 5、测试: 时间会比较长&#xff0…

智能AI写作系统+ChatGPT程序源码搭建部署教程+支持GPT4.0/AI绘画

一、SparkAI智能创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文…

Ngnix封禁IP与ip段

Ngnix IP封禁以及实现自动封禁IP 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.创建文件&#xff08;被封禁的ip写里面&#xff09; 在ngnix的conf目录下创建一个blockip.conf文件&#xff0c;里面放需要封禁的IP与ip段&#xff0c;格式如下&#xff08;deny是禁用…

【工作记录】MQTT介绍、安装部署及springboot集成@20230912

背景 近期公司可能会有物联网设备相关项目内容&#xff0c;提前对用到的mqtt协议做预研和初步使用。 最初接触到mqtt协议应该是早些年的即时通讯吧&#xff0c;现在已经是物联网设备最热门的协议了。 作为记录&#xff0c;也希望能帮助到需要的朋友。 MQTT介绍 《MQTT 协议规…

Linux IO函数

read/write函数&#xff1a; 1.read #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 参数&#xff1a; -fd&#xff1a;文件描述符&#xff0c;open得到的&#xff0c;通过这个文件描述符操作某个文件 -buf&#xff1a;需要读取数据存放的地方…