• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > shared_ptr线程安全性全面分析

shared_ptr线程安全性全面分析

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了shared ptr,boost shared ptr,std shared ptr,shared ptr 头文件,shared ptr reset等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

正如《STL源码剖析》所讲,“源码之前,了无秘密”。本文基于shared_ptr的源代码,提取了shared_ptr的类图和对象图,然后分析了shared_ptr如何保证文档所宣称的线程安全性。本文的分析基于boost 1.52版本,编译器是VC 2010。

shared_ptr的线程安全性
boost官方文档对shared_ptr线程安全性的正式表述是:shared_ptr对象提供与内置类型相同级别的线程安全性。【shared_ptrobjects offer the same level of thread safety as built-in types.】具体是以下三点。

1. 同一个shared_ptr对象可以被多线程同时读取。【A shared_ptrinstance can be "read" (accessed using only const operations)simultaneously by multiple threads.】

2. 不同的shared_ptr对象可以被多线程同时修改(即使这些shared_ptr对象管理着同一个对象的指针)。【Different shared_ptr instances can be "written to"(accessed using mutable operations such as operator= or reset) simultaneouslyby multiple threads (even when these instances are copies, and share the samereference count underneath.) 】

3. 任何其他并发访问的结果都是无定义的。【Any other simultaneous accesses result in undefined behavior.】

第一种情况是对对象的并发读,自然是线程安全的。

第二种情况下,如果两个shared_ptr对象A和B管理的是不同对象的指针,则这两个对象完全不相关,支持并发写也容易理解。但如果A和B管理的是同一个对象P的指针,则A和B需要维护一块共享的内存区域,该区域记录P指针当前的引用计数。对A和B的并发写必然涉及对该引用计数内存区的并发修改,这需要boost做额外的工作,也是本文分析的重点。

另外weak_ptr和shared_ptr紧密相关,用户可以从weak_ptr构造出shared_ptr,也可以从shared_ptr构造weak_ptr,但是weak_ptr不涉及到对象的生命周期。由于shared_ptr的线程安全性是和weak_ptr耦合在一起的,本文的分析也涉及到weak_ptr。

下面先从总体上看一下shared_ptr和weak_ptr的实现。

shared_ptr的结构图
以下是从boost源码提取出的shared_ptr和weak_ptr的类图。




我们首先忽略虚线框内的weak_ptr部分。最高层的shared_ptr就是用户直接使用的类,它提供shared_ptr的构造、复制、重置(reset函数)、解引用、比较、隐式转换为bool等功能。它包含一个指向被管理对象的指针,用来实现解引用操作,并且组合了一个shared_count对象,用来操作引用计数。

但shared_count类还不是引用计数类,它只是包含了一个指向引用计数类sp_counted_base的指针,功能上是对sp_counted_base操作的封装。shared_count对象的创建、复制和删除等操作,包含着对sp_counted_base的增加和减小引用计数的操作。

最后sp_counted_base类才保存了引用计数,并且对引用计数字段提供无锁保护。它也包含了一个指向被管理对象的指针,是用来删除被管理的对象的。sp_counted_base有三个派生类,分别处理用户指定Deleter和Allocator的情况:

1. sp_counted_impl_p:用户没有指定Deleter和Allocator

2. sp_counted_impl_pd:用户指定了Deleter,没有指定Allocator

3. sp_counted_impl_pda:用户指定了Deleter和 Allocator

创建指针P的第一个shared_ptr对象的时候,子对象shared_count同时被建立, shared_count根据用户提供的参数选择创建一个特定的sp_counted_base派生类对象X。之后创建的所有管理P的shared_ptr对象都指向了这个独一无二的X。

然后再看虚线框内的weak_ptr就清楚了。weak_ptr和shared_ptr基本上类似,只不过weak_ptr包含的是weak_count子对象,但weak_count和shared_count也都指向了sp_counted_base。

如果上面的文字还不够清楚,下面的代码就能说明问题。

shared_ptr<SomeObject> SP2=SP1;

weak_ptr<SomeObject> WP1=SP1;
</div>
执行完以上代码后,内存中会创建以下对象实例,其中红色箭头表示指向引用计数对象的指针,黑色箭头表示指向被管理对象的指针。




从上面可以清楚的看出,SP1、SP2和WP1指向了同一个sp_counted_impl_p对象,这个sp_counted_impl_p对象保存引用计数,是SP1、SP2和WP1等三个对象共同操作的内存区。多线程并发修改SP1、SP2和WP1,有且只有sp_counted_impl_p对象会被并发修改,因此sp_counted_impl_p的线程安全性是shared_ptr以及weak_ptr线程安全性的关键问题。而sp_counted_impl_p的线程安全性是在其基类sp_counted_base中实现的。下面将着重分析sp_counted_base的代码。

引用计数类sp_counted_base
幸运的是,sp_counted_base的代码量很小,下面全文列出来,并添加有注释。
        if( _InterlockedDecrement( &use_count_ ) == 0 )

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++智能指针shared_ptr分析
  • C++中auto_ptr智能指针的用法详解
  • C++中的auto_ptr智能指针的作用及使用方法详解
  • 详解C++中shared_ptr的使用教程
  • shared_ptr线程安全性全面分析
  • 浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr
  • C++开发:为什么多线程读写shared_ptr要加锁的详细介绍

相关文章

  • 2017-05-28C++实现简单的职工信息管理系统
  • 2017-05-28C语言数据结构 栈的基础操作
  • 2017-05-28基于C语言中段错误的问题详解
  • 2017-05-28探讨++i与i++哪个效率更高
  • 2017-05-28用C语言的泛型实现交换两个变量值
  • 2017-05-28C++中抽象类和接口的区别介绍
  • 2017-05-28VC判断一个文件为目录的方法
  • 2017-05-28VC下实现fopen支持中文的方法
  • 2017-05-28简单谈谈C++ 头文件系列之(iosfwd)
  • 2017-05-28学习C++编程的必备软件

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++实现将简单密码译回原文的方法
    • C语言中函数参数的入栈顺序详解及实例
    • c语言中位字段与结构联合的组合使用详解
    • C语言左旋转字符串与翻转字符串中单词顺序的方法
    • 浅谈C++的浅拷贝出现的错误
    • C语言中获取进程识别码的相关函数
    • 用C++面向对象的方式动态加载so的方法
    • Codeforces 842A. Kirill And The Game (暴力算法比较)
    • C语言中对字母进行大小写转换的简单方法
    • C++类静态成员与类静态成员函数详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有