互斥锁:

假设我们要在多线程中实现背景图片的控制:

class PrettyMenu{
public:……void changeBackground(std::istream& imgSrc);//改变背景图片……
private:Mutex mutex;    //互斥量Image* bgImage; //当前背景图片int imageChanges;   //背景图片改变次数
};void PrettyMenu::changeBackground(std::istream& imgSrc)
{lock(&mutex);delete bgImage;++imageChanges;bgImage=new Image(imgSrc);unlock(&mutex);
}

但是上面这些会遇到两个问题:

  • 如果 new Image(imgSrc)发生了异常,那么unlock就不会被执行,会被一直锁住
  • 发生上面异常,imageChanges也被累加,但实际上新的图片没有被安装

对于第一个问题:

被及时释放的互斥锁:

share_ptr我们可以指定它的删除器,所以可以在删除器中释放互斥锁.
如此即使是发生了异常,互斥锁也能够被及时的释放。

class Lock{
public:explicit Lock(Mutex* mu):mutexPtr(mu,unlock)//以某个Mutex初始化,unlock作为删除其{lock(mutexPtr);}
private:shared_prt<Mutex> mutexPtr;
};

如果通过一个Lock类,然后在析构函数阶段进行 unlock也可以避免这个问题。但是这样的类进行复制的时候
可能存在很多不合理的问题。
如果希望保存资源直到最后一个对象消失,并且在复制的时候是引用计数,可以使用上面这种情况。


对于第二个问题:

swap的 全or无:

struct PMImpl{ std::tr1::shared_ptr<Image> bgImage;int imageChanges;
};
class PrettyMenu{……
private:Mutex mutex;std::tr1::shared_ptr<PMImpl> pImpl;
};void PrettyMenu::changeBackground(std::istream& imgSrc)
{using std::swap;//**条款**25Lock m1(&mutex);std::tr1::shared_ptr<PMImpl> pNew(new PMImpl(*pImpl));pNew->bgImage.reset(new Image(imgSrc));;//修改副本++pNew->imageChanges;swap(pImpl,pNew);
}

我们可以先弄一个副本,在进行完所有的操作之后,再与目标对象进行交换。
从而实现: 要不然就不处理,不然就全部处理完。
所以我们需要一个 不会抛出异常的swap操作。


参考:

《Effective C++》

转载于:https://www.cnblogs.com/Przz/p/6628896.html

为了异常安全(swap,share_ptr)——Effecive C++相关推荐

  1. 《Effective C++》学习笔记(条款25:考虑写出一个不抛异常的swap函数)

    最近开始看<Effective C++>,为了方便以后回顾,特意做了笔记.若本人对书中的知识点理解有误的话,望请指正!!! swap函数是一个非常经典又有用的函数,除了它本身用来交换两个对 ...

  2. 《Effective C++》item25:考虑写出一个不抛异常的swap函数

    std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _T ...

  3. 25 考虑写出一个不抛异常的swap

    一.std::swap std::swap面对指针(如pImpl写法)时效率低,因此需要重写swap 1.1 如何重写swap 为标准库提供特化版本(全特化) //pImpl写法的Widget cla ...

  4. Linux 交换内存空间原理(swap)(Linux内存管理)(cgroups)

    文章目录 什么是swap? 为什么需要swap? swap的缺点? 到底要不要swap? 内存不够用 内存勉强够用 内存充裕 桌面环境 服务器环境 swap大小配置多少比较合适? 怎么配置swap? ...

  5. Centos7 合理分配 swap空间

    一:查看服务器内存情况命令: #free 可以看到,我的服务器还没有配置Swap虚拟内存! 第二步:检查硬盘驱动器分区上的可用空间 在我们创建swap文件之前,我们将检查当前的磁盘使用情况,以确保我们 ...

  6. Ramdisk虚拟内存盘,Swap分区

    虚拟内存盘是通过软件将一部分内存(RAM)模拟为硬盘来使用的一种技术.相对于直接的硬盘文件访问来说,这种技术可以极大的提高在其上进行的文件访问的速度.但是RAM的易失性也意味着当关闭电源后这部分数据将 ...

  7. Linux swap分区

    转自:https://segmentfault.com/a/1190000008125116 什么是swap? swap space是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组 ...

  8. c++语言swap函数,C++中swap函数

    本文是我用到swap函数时,对其产生好奇,所以结合网上有关博文写下的.个人水平有限,若有错误的地方,欢迎留言指出.谢谢! 一.通用的函数交换模板 template void swap(T &a ...

  9. 读书笔记 来自网络

    2010年3月15日 # <深入解析MFC>笔记 12. 进程与线程 2009-10-7 ======================= <深入解析MFC>笔记 12. 进程与 ...

最新文章

  1. linux调试C++错误: 程序中有游离的‘\240’‘\302’
  2. Vscode 过滤.pyc文件
  3. U盘为什么还有剩余空间,但却提示说空间不够
  4. bzoj 4551: [Tjoi2016Heoi2016]树【并查集】
  5. Solr 搭建搜索服务器
  6. python调用函数怎么表示_Python---7函数(调用定义函数)
  7. Python 获取系统信息模块psutil(转载)
  8. css开发语言,盘点5大主流CSS框架,你知道哪些
  9. Python解析pdf转为TXT格式
  10. python函数转换_将Python函数转换为PL/Python函数
  11. ssms win10_10个SSMS技巧和窍门可提高您的生产力
  12. linux下定时执行任务方法【转】
  13. 如何在 Linux 终端中复制粘贴 [初学者教程]
  14. Poj1469_匈牙利算法_最大二分匹配
  15. OpenCV的图像分类基础知识
  16. 主分区损坏diskgenius_使用Diskgenius完成磁盘结构损坏且无法读取的的情况
  17. ELK-logstash 的 grok与dissect 测试应用
  18. 【pytorch】 grad、grad_fn、requires_grad()、with torch.no_grad() 、net.train()、net.eval():记录一次奇怪的debug经历
  19. XDM2020 Java版类似IDM微软下载器的开源下载工具编译
  20. 因果推断, 因果效应概述

热门文章

  1. 题目1452:搬寝室(dp题目)
  2. DEDECMS 关键字不能小于2个字节!
  3. 数据科学可视化之要途
  4. Linux底下apache服务器日志按日期分割
  5. idea 提示 Cannot resolve symbol ‘log‘解决
  6. SpringBoot中使用Hibernate Validator校验工具类
  7. YangTools从YANG生成Java类(Maven)
  8. leetcodeT14-最长公共前缀(两种解法+图解)
  9. 动态规划(五)——0/1背包
  10. oracle 转 mysql 乱码问题吗_Oracle数据传输MySQL中文编码问题