<Linux多线程服务端编程>学习记录

来源:互联网 发布:c语言图书管理系统 编辑:程序博客网 时间:2024/05/17 04:08


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

有这样一个场景

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

代码如下:

#include <functional>#include <memory>#include <string>#include <map>#include <assert.h>#include <mutex>using std::string;class Stock {public:    Stock(const string& name)        : name_(name)    {        printf("Stock[%p] %s\n", this, name_.c_str());    }    ~Stock()    {        printf("~Stock[%p] %s\n", this, name_.c_str());    }    const string& key() const { return name_; }private:    string name_;};// questionable codeclass StockFactory {public:    std::shared_ptr<Stock> get(const string& key)    {        std::lock_guard<std::mutex> lock(mutex_);        std::shared_ptr<Stock>& pStock = stocks_[key];        if (!pStock)        {            pStock.reset(new Stock(key));        }        return pStock;    }private:    std::mutex mutex_;    std::map<string, std::shared_ptr<Stock> > stocks_;};int main(){    StockFactory sf1;    {        std::shared_ptr<Stock> s1 = sf1.get("stock1");    }    printf("s1 should destruct\n");    return 0;}cpp1


 运行显示如下

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

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

 

代码如下

#include <functional>#include <memory>#include <string>#include <map>#include <assert.h>#include <mutex>using std::string;class Stock {public:    Stock(const string& name)        : name_(name)    {        printf("Stock[%p] %s\n", this, name_.c_str());    }    ~Stock()    {        printf("~Stock[%p] %s\n", this, name_.c_str());    }    const string& key() const { return name_; }private:    string name_;};// questionable codeclass StockFactory {public:    std::shared_ptr<Stock> get(const string& key)    {        std::shared_ptr<Stock> pStock;        std::lock_guard<std::mutex> lock(mutex_);        std::weak_ptr<Stock>& wkStock = stocks_[key];        pStock = wkStock.lock();        if (!pStock)        {            pStock.reset(new Stock(key));            wkStock = pStock;        }        return pStock;    }private:    std::mutex mutex_;    std::map<string, std::weak_ptr<Stock> > stocks_;};int main(){    StockFactory sf2;    {        std::shared_ptr<Stock> s1 = sf2.get("stock2");    }    printf("s1 should destruct\n");    return 0;}cpp2


运行显示如下

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

 

 

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

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

// 11111.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <functional>#include <memory>#include <string>#include <map>#include <assert.h>#include <mutex>using std::string;class Stock {public:    Stock(const string& name)        : name_(name)    {        printf("Stock[%p] %s\n", this, name_.c_str());    }    ~Stock()    {        printf("~Stock[%p] %s\n", this, name_.c_str());    }    const string& key() const { return name_; }private:    string name_;};class StockFactory {public:    std::shared_ptr<Stock> get(const string& key)    {        std::shared_ptr<Stock> pStock;        std::lock_guard<std::mutex> lock(mutex_);        std::weak_ptr<Stock>& wkStock = stocks_[key];        pStock = wkStock.lock();        if (!pStock)        {            pStock.reset(new Stock(key),                std::bind(&StockFactory::deleteStock, this, std::placeholders::_1));            wkStock = pStock;        }        return pStock;    }private:    void deleteStock(Stock* stock)    {        printf("deleteStock[%p]\n", stock);        if (stock)        {            std::lock_guard<std::mutex> lock(mutex_);            stocks_.erase(stock->key());        }        delete stock;  // sorry, I lied    }    std::mutex mutex_;    std::map<string, std::weak_ptr<Stock> > stocks_;};void testLongLifeFactory(){    std::shared_ptr<StockFactory> factory(new StockFactory);    {        std::shared_ptr<Stock> stock = factory->get("NYSE:IBM");        std::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM");        assert(stock == stock2);        // stock destructs here    }    // factory destructs here}void testShortLifeFactory(){    std::shared_ptr<Stock> stock;    {        std::shared_ptr<StockFactory> factory(new StockFactory);        stock = factory->get("NYSE:IBM");        std::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM");        assert(stock == stock2);        // factory destructs here    }    // stock destructs here}int main(){    StockFactory sf3;    {        std::shared_ptr<Stock> s3 = sf3.get("stock3");    }    printf("s1 should destruct\n");    testLongLifeFactory();    testShortLifeFactory();//此处出错 因为我们BIND函数的时候使用的是this指针 而STOCK析构的时候 FACTORY早已不在    return 0;}


解决办法视阅读回复量再决定是否继续

 

技术博客 http://blog.csdn.net/stecdeng 技术交流群 群号码:324164944 欢迎c c++ windows驱动爱好者 服务器程序员沟通交流

0 0