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


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

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

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

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

    欢迎关注Android系统攻城狮

    1.前言

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

    2.应用实例

    <1>.shared_ptr死锁

    #include 
    #include 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

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

    <2>.shared_ptr解锁

    #include 
    #include 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    #include 
    #include 
    #include 
    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 pb(new Test2());
      // shared_ptr pa(new Test1());
      // pb->pa_ = pa;
      // pa->pb_ = pb;
    
      //v2.0
      shared_ptr<Test1> pa = make_shared<Test1>();
      shared_ptr<Test2> pb = make_shared<Test2>();
      pb->pa_ = pa;
      pa->pb_ = pb;
    
      //由于share_ptr是共享资源,所以pb所指向的资源的引用计数也会加1
      cout << "pb.use_count " << pb.use_count() << endl;//2
      cout << "pa.use_count " << pa.use_count() << endl;//2
    
    }//程序结束时,没有调用Test1和Test2的析构函数
    
    int main(){
      test();
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    <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 
    #include 
    #include 
    using namespace std;
    
    class Test2;
    class Test1{
    public:
      //shared_ptr 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 pb(new Test2());
      // shared_ptr pa(new Test1());
      // pb->pa_ = pa;
      // pa->pb_ = pb;
    
      //v2.0
      shared_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;//2
      cout << "pa.use_count " << pa.use_count() << endl;//2
    
    }
    int main(){
      test();
      return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    将shared_ptr改为weak_ptr弱智能指针。

  • 相关阅读:
    图解LeetCode——1694. 重新格式化电话号码(难度:简单)
    用一张图说一说 ChatGPT 内部技术工作流程
    解决vs code终端无法执行命令的问题
    Spring Data JPA与Mybatis的对比
    我眼中的大数据(一)
    一个非常实用的分布式 JVM 监控工具
    【Pytorch报错】RuntimeError:cuDNN error:CUDNN_STATUS_INTERNAL_ERROR 高效理解记录及解决!
    爬虫的http和https基础
    【C++】unordered_map和unordered_set
    10贪心:柠檬水找零
  • 原文地址:https://blog.csdn.net/u010164190/article/details/132843549