<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
- <Linux多线程服务端编程>学习记录
- 《Linux多线程服务端编程》学习笔记---第一章
- 评:Linux多线程服务端编程
- linux网络编程学习笔记之四 -----多线程并发服务端
- Linux多线程服务端编程(笔记1)
- Linux多线程服务端编程(笔记2)
- Linux多线程服务端编程:使用muduo C++网络库
- Linux多线程服务端编程(笔记3_4)
- 《linux多线程服务端编程--muduo网络库的使用》读后感
- Linux下的TCP/IP编程----线程及多线程服务端
- 《Linux多线程服务端编程》—线程同步精要
- 《Linux多线程服务端编程》—muduo网络库(1)
- 《linux多线程服务端编程muduo网络库的使用》读后感
- 《Linux多线程服务端编程》笔记——线程同步精要
- linux多线程服务端编程读书笔记——第三章
- 初探《Linux多线程服务端编程 使用muduo C++网络库》
- 《Linux多线程服务端》读书笔记——学习路线
- Linux下多线程编程学习
- redis数据库
- SpringMVC文件上传下载
- spark 中 rdd to dataframe 问题
- Linux学习之I/O内存访问详解
- Hive源码调试步骤
- <Linux多线程服务端编程>学习记录
- Java 网络编程简单学习笔记1
- 关于adb
- 72. Edit Distance
- HDU 4876 ZCC loves cards
- ubuntu中配置samba方法
- CentOS中更改IPV4和IPV6地址以及路由
- 307. Range Sum Query
- 关于锁(悲观锁与乐观锁)