<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字符串当成人类可读的文本,码位当成机器可读的, 将字节序列编程人类可读是解码,把字符串编码成字节序列是编码 ...
随机推荐
- Git 代码版本还原方法
因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,Git 代码版本还原方法 在使用 Git 管理自己的代码和资料时,难免会遇到意料 ...
- angular 参考文档
https://www.w3schools.com/angular/ 参考二: https://www.angular.cn/guide/reactive-forms
- html页面中iframe导致JavaScript失效
<body onload=“reset()”> <div id="part1"> some thing here .... <div> < ...
- ccttp图片处理过程
1.python输出404的图片 #!/usr/bin/python # coding: utf-8 import psycopg2 import sys from datetime import * ...
- 一个js程序:离下一个圣诞节还有多少天?
话不多说上代码: //离下一个圣诞节还有多少天 var christ=new Date(); christ.setMonth(11); christ.setDate(25); var year=now ...
- vim使用方法:
vim使用方法: 模式: 编辑模式.未编辑模式.命令行模式 i 插入形式进入编辑模式 a 增加 o 下行编辑 O 上行插入 : 进入命令行模式 esc 退出编辑模式 wq 保存文件 yy 复制 p 粘 ...
- pipeenv error
[root@mhc tmp]# pipenv --python 3.6Creating a virtualenv for this project…Using /root/python3/bin/py ...
- 用R进行统计学分析
1.基本统计 summary函数:R中的summary函数根据输入的类提供输入的摘要.该函数根据输入对象的类调用各种函数.返回值也取决于输入对象.例如,如果输入是一个由数字数据组成的向量,它将为数据提 ...
- mysql物理备份
原本以为直接将data文件夹下每个数据库对应的文件夹拷贝到新的MySQL的data文件夹就可以了,其实不然. 这样做有几个问题: 1.如果是用了引擎的表,还需要复制ibdata文件,并且frm文件所在 ...
- webpack 常用插件及作用
copy-webpack-plugin :复制文件到目标文件夹.在开发时使用热模替换,(没有生成dist 文件夹,都在内存中),如果想引用某一个js文件,直接写script标签是找不到的,因为服务器内 ...