zoukankan      html  css  js  c++  java
  • <Linux多线程服务端编程>学习记录

    使用智能指针解决多线程下 类的解析冲突问题

    有这样一个场景

    使用StockFactory记录Stock的信息  容器是map<string,smart_ptr>;

    代码如下:

     1 #include <functional>
     2 #include <memory>
     3 #include <string>
     4 #include <map>
     5 #include <assert.h>
     6 #include <mutex>
     7 
     8 using std::string;
     9 
    10 class Stock 
    11 {
    12 public:
    13     Stock(const string& name)
    14         : name_(name)
    15     {
    16         printf("Stock[%p] %s
    ", this, name_.c_str());
    17     }
    18 
    19     ~Stock()
    20     {
    21         printf("~Stock[%p] %s
    ", this, name_.c_str());
    22     }
    23 
    24     const string& key() const { return name_; }
    25 
    26 private:
    27     string name_;
    28 };
    29 
    30 
    31 // questionable code
    32 class StockFactory 
    33 {
    34 public:
    35 
    36     std::shared_ptr<Stock> get(const string& key)
    37     {
    38         std::lock_guard<std::mutex> lock(mutex_);
    39         std::shared_ptr<Stock>& pStock = stocks_[key];
    40         if (!pStock)
    41         {
    42             pStock.reset(new Stock(key));
    43         }
    44         return pStock;
    45     }
    46 
    47 
    48 private:
    49     std::mutex mutex_;
    50     std::map<string, std::shared_ptr<Stock> > stocks_;
    51 };
    52 
    53 
    54 
    55 int main()
    56 {
    57     StockFactory sf1;
    58     {
    59         std::shared_ptr<Stock> s1 = sf1.get("stock1");
    60     }
    61     printf("s1 should destruct
    ");
    62 
    63     return 0;
    64 }
    cpp1

     运行显示如下

    Stock[007E8818] stock1
    s1 should destruct
    ~Stock[007E8818] stock1
    没有按照预想的进行析构

    说明我们的map容器应该使用弱指针weak_ptr,否则就会出现STOCKFACTOR不析构,STOCK也不会析构的强引用

    代码如下

     1 #include <functional>
     2 #include <memory>
     3 #include <string>
     4 #include <map>
     5 #include <assert.h>
     6 #include <mutex>
     7 
     8 using std::string;
     9 
    10 class Stock 
    11 {
    12 public:
    13     Stock(const string& name)
    14         : name_(name)
    15     {
    16         printf("Stock[%p] %s
    ", this, name_.c_str());
    17     }
    18 
    19     ~Stock()
    20     {
    21         printf("~Stock[%p] %s
    ", this, name_.c_str());
    22     }
    23 
    24     const string& key() const { return name_; }
    25 
    26 private:
    27     string name_;
    28 };
    29 
    30 
    31 // questionable code
    32 class StockFactory 
    33 {
    34 public:
    35     std::shared_ptr<Stock> get(const string& key)
    36     {
    37         std::shared_ptr<Stock> pStock;
    38         std::lock_guard<std::mutex> lock(mutex_);
    39         std::weak_ptr<Stock>& wkStock = stocks_[key];
    40         pStock = wkStock.lock();
    41         if (!pStock)
    42         {
    43             pStock.reset(new Stock(key));
    44             wkStock = pStock;
    45         }
    46         return pStock;
    47     }
    48 
    49 private:
    50     std::mutex mutex_;
    51     std::map<string, std::weak_ptr<Stock> > stocks_;
    52 };
    53 
    54 
    55 
    56 int main()
    57 {
    58     StockFactory sf2;
    59     {
    60         std::shared_ptr<Stock> s1 = sf2.get("stock2");
    61     }
    62     printf("s1 should destruct
    ");
    63 
    64     return 0;
    65 }
    cpp2

     运行显示如下

    Stock[00468818] stock2
    ~Stock[00468818] stock2
    s1 should destruct

     

    运行情况与我们预想的情况一致 下面的问题就是我们使用的map容器中,当STOCK解析了,map却没有将其智能指针移除

    所以在使用智能指针的时候我们要订制析构函数

      1 // 11111.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 #include <functional>
      6 #include <memory>
      7 #include <string>
      8 #include <map>
      9 #include <assert.h>
     10 #include <mutex>
     11 
     12 using std::string;
     13 
     14 class Stock 
     15 {
     16 public:
     17     Stock(const string& name)
     18         : name_(name)
     19     {
     20         printf("Stock[%p] %s
    ", this, name_.c_str());
     21     }
     22 
     23     ~Stock()
     24     {
     25         printf("~Stock[%p] %s
    ", this, name_.c_str());
     26     }
     27 
     28     const string& key() const { return name_; }
     29 
     30 private:
     31     string name_;
     32 };
     33 
     34 
     35 class StockFactory 
     36 {
     37 public:
     38 
     39     std::shared_ptr<Stock> get(const string& key)
     40     {
     41         std::shared_ptr<Stock> pStock;
     42         std::lock_guard<std::mutex> lock(mutex_);
     43         std::weak_ptr<Stock>& wkStock = stocks_[key];
     44         pStock = wkStock.lock();
     45         if (!pStock)
     46         {
     47             pStock.reset(new Stock(key),
     48                 std::bind(&StockFactory::deleteStock, this, std::placeholders::_1));
     49             wkStock = pStock;
     50         }
     51         return pStock;
     52     }
     53 
     54 private:
     55 
     56     void deleteStock(Stock* stock)
     57     {
     58         printf("deleteStock[%p]
    ", stock);
     59         if (stock)
     60         {
     61             std::lock_guard<std::mutex> lock(mutex_);
     62             stocks_.erase(stock->key());
     63         }
     64         delete stock;  // sorry, I lied
     65     }
     66     std::mutex mutex_;
     67     std::map<string, std::weak_ptr<Stock> > stocks_;
     68 };
     69 
     70 
     71 void testLongLifeFactory()
     72 {
     73     std::shared_ptr<StockFactory> factory(new StockFactory);
     74     {
     75         std::shared_ptr<Stock> stock = factory->get("NYSE:IBM");
     76         std::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM");
     77         assert(stock == stock2);
     78         // stock destructs here
     79     }
     80     // factory destructs here
     81 }
     82 
     83 void testShortLifeFactory()
     84 {
     85     std::shared_ptr<Stock> stock;
     86     {
     87         std::shared_ptr<StockFactory> factory(new StockFactory);
     88         stock = factory->get("NYSE:IBM");
     89         std::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM");
     90         assert(stock == stock2);
     91         // factory destructs here
     92     }
     93     // stock destructs here
     94 }
     95 
     96 
     97 int main()
     98 {
     99     StockFactory sf3;
    100     {
    101         std::shared_ptr<Stock> s3 = sf3.get("stock3");
    102     }
    103     printf("s1 should destruct
    ");
    104 
    105     testLongLifeFactory();
    106     testShortLifeFactory();//此处出错 因为我们BIND函数的时候使用的是this指针 而STOCK析构的时候 FACTORY早已不在
    107 
    108     return 0;
    109 }
    View Code

    剩下的视阅读回复量再决定是否继续

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    python2.7之打飞机(文末附素材链接)
    python画小猪佩奇
    什么叫递归
    DIV居中的几种方法
    什么是控制反转
    上传图片及时预览
    MVC与三层的区别
    From表单提交刷新页面?
    文件上传之form表单篇
    文件上传之伪Ajax篇
  • 原文地址:https://www.cnblogs.com/itdef/p/6484121.html
Copyright © 2011-2022 走看看