<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\n", this, name_.c_str());
17     }
18 
19     ~Stock()
20     {
21         printf("~Stock[%p] %s\n", 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\n");
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\n", this, name_.c_str());
17     }
18 
19     ~Stock()
20     {
21         printf("~Stock[%p] %s\n", 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\n");
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\n", this, name_.c_str());
 21     }
 22 
 23     ~Stock()
 24     {
 25         printf("~Stock[%p] %s\n", 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]\n", 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\n");
104 
105     testLongLifeFactory();
106     testShortLifeFactory();//此处出错 因为我们BIND函数的时候使用的是this指针 而STOCK析构的时候 FACTORY早已不在
107 
108     return 0;
109 }
View Code

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

 

posted on 2017-03-01 14:28  itdef  阅读(221)  评论(0编辑  收藏  举报

导航