<Linux多线程服务端编程>学习记录
使用智能指针解决多线程下 类的解析冲突问题
有这样一个场景
使用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 code
class 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 ;
}
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 code
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));
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 ;
}
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 ;
}
剩下的视阅读回复量再决定是否继续
<Linux多线程服务端编程>学习记录的更多相关文章
- Python灰帽子:黑客与逆向工程师的Python编程之道|百度网盘免费下载|新手黑客入门
百度网盘免费下载:Python灰帽子:黑客与逆向工程师的Python编程之道 提取码:tgpg 目录 · · · · · · 第1章 搭建开发环境 11.1 操作系统要求 11.2 获取和安装Pyt ...
- Python灰帽子:黑客与逆向工程师的Python编程之道PDF高清完整版免费下载|百度云盘
百度云盘免费下载:Python灰帽子:黑客与逆向工程师的Python编程之道PDF高清完整版免费下载 提取码:8nki 目录 · · · · · · 第1章 搭建开发环境 11.1 操作系统要求 1 ...
- 《灰帽Python-黑客和逆向工程师的Python编程》学习记录
ctypes是Python语言的一个外部库,提供和C语言兼容的数据类型,可以很方便的调用C DLL中的函数. 操作环境:CentOS6.5 Python版本:2.66 ctypes是强大的,强大到本书 ...
- 【Python灰帽子--黑客与逆向工程师的Python编程之道】我的学习笔记,过程.(持续更新HOT)
我的学习笔记---python灰帽子 世界让我遍体鳞伤,但伤口长出的却是翅膀. -------------------------------------------- 前言 本书是由知名安全机构Im ...
- python核心编程学习记录之映射和集合类型
字典是python里唯一的映射类型
- python核心编程学习记录之Python对象
比较符号如<,>,=比较的是对象的值 如果要比较对象本身要用is,is not repr()的功能与''所做的事情是一样的 Python不支持的类型有char,byte,指针,short, ...
- python核心编程学习记录之基础知识
虽然对python的基础知识有所了解,但是为了更深入的学习,要对python的各种经典书籍进行学习 第一章介绍python的优缺点,略过 第二章介绍python起步,第三章介绍python基础,仅记录 ...
- Python大神成长之路: 第一次学习记录
一.Python发展史 二.Python2 or 3 博主选择了Python3. 从官网下载Python www.python.org Windows安装python3.5.python2.7.安装 ...
- 流畅的python第十九章元编程学习记录
在 Python 中,数据的属性和处理数据的方法统称属性(attribute).其实,方法只是可调用的属性.除了这二者之外,我们还可以创建特性(property),在不改变类接口的前提下,使用存取方法 ...
- 流畅的python第四章文本和字节序列学习记录
字符问题 把码位转化成字节序列的过程是编码,把字节序列转化成码位的过程是解码 把unicode字符串当成人类可读的文本,码位当成机器可读的, 将字节序列编程人类可读是解码,把字符串编码成字节序列是编码 ...
随机推荐
- 可视化学习Tensorboard
可视化学习Tensorboard TensorBoard 涉及到的运算,通常是在训练庞大的深度神经网络中出现的复杂而又难以理解的运算.为了更方便 TensorFlow 程序的理解.调试与优化,发布了一 ...
- 地址解析协议ARP(Address Resolution Protocol)
1.引言 说明: ARP的作用,解决了什么问题: 以太网中的链路层,可能会采用不同的网络技术,而且不以ip作为路由依据. 链路层以mac地址作为路由依据. ARP的功能是在32 bit的IP地址和采用 ...
- VMware vCenter Server 6.5.0 U1g
VMware vCenter Server 6.5.0 U1gName: VMware-VCSA-all-6.5.0-8024368.iso Release Date: 2018-03-20 Buil ...
- 亿图eddx与visio转换
Visio支持的格式 AutoCAD 绘图文件格式 (.dwg..dxf) 压缩增强型图元文件 (.emz) 增强型图元文件 (.emf) 可交换图像文件格式 (GIF) JPEG 文件交换格式 (. ...
- curl 请求https内容,返回空
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$api); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);/ ...
- jsfl 发布保存关闭
fl.getDocumentDOM().publish(); fl.getDocumentDOM().save(); fl.getDocumentDOM().close();
- 前端开发-3-HTML-body标签
body标签 h.p.a.ul.ol.div.img. 想要在网页上展示出来的内容一定要放在body标签中. 把我们之前海燕那一段HTML代码贴过来,保存到一个HTML格式的文件中. <!DOC ...
- locate包的安装
linux中locate命令可以快速定位我们需要查找的文件,但是在yum中,locate的安装包名为 mlocate(yum list | grep locate可以查看),安装方法: yum -y ...
- sql server判断是否为null
sql server 替换null:isnull(arg,value) 如:select isnull(price,0.0) from orders ,如果price为null的话,用0.0替换 与n ...
- NodeJS框架express的路径映射(路由)功能及控制
我 们知道Express是一个基于NodeJS的非常优秀的服务端开发框架,本篇CSSer将提供express框架的route和route control章节,route实现了客户端请求的URL的路径映 ...