中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
采用路经检测法(Checking Road)解决 Double Checked Locking 的缺陷
作者:未知 时间:2005-07-27 23:30 出处:CSDN 责编:chinaitpower
              摘要:采用路经检测法(Checking Road)解决 Double Checked Locking 的缺陷
Double Checked Locking模式: class Singleton { public: static Singleton *instance (void) { if (instance_ == 0) { Guard lock (lock_) if (instance_ == 0) { instance_ = new Singleton; } } return instance_; } private: static Singleton *instance_; }; 上面所说的Double Checked Locking模式有下面优点: 1、最小化加锁。通过实现两个flag检测(第一个flag采用模糊匹配,第二个flag采用精确定位),Double Checked Locking模式实现通常用例的优化。 但是同时此模式存在也会带来致命的缺陷: 1、如果使用Double Checked Locking模式的软件被移植到没有原子性的指针和正数赋值语义的硬件平台上。例如,如果一个instance_指针被用来作为Singleton实现的flag,instance_指针中的所有位(bit)必须在一次操作中完成读和写。如果将new的结果写入内存不是一个原子操作,其他的线程可能会试图读取一个不健全的指针,这将导致非法的内存访问。在一些允许内存地址跨越对齐边界的系统上这种现象是可能的,因此每次访问需要从内存中取两次。在这种情况下,系统可能使用分离的字对齐合成flag,来表示 instance_指针。 2、某些编译器可能在优化过程中采用某种缓冲手段来优化flag,或是移除了第二个flag==0检测。 针对这两个缺陷,现在我们提出了一种解决方案: Double Checked Locking 模式: 01 class Singleton 02 { 03 public: 04 static Singleton *instance (void) 05 { 06 // 第一个模糊检测 07 if (instance_ == 0) 08 { 09 //模糊区域 10 Guard guard (lock_); 11 // 第二次检测 12 if (instance_ == 0) //精确定位 13 instance_ = new Singleton; 14 } 15 return instance_; 16 // 释放锁. 17 } 18 private: 19 static Mutex lock_; 20 static Singleton *instance_; 21 }; 改进版本的Double Checked Locking 模式: 01 class Singleton 02 { 03 public: 04 static Singleton *instance (void) 05 { 06 // 第一个模糊检测 07 if (instance_test_ == 0)//<=if (instance_ == 0) 08 { 09 //模糊区域 10 Guard guard (lock_); 11 // 第二次检测 12 if (instance_ == 0)//精确定位 A1 { 13 instance_ = new Singleton; A2 instance_test_ = instance; A3 } 14 } 15 return instance_; 16 // 释放锁. 17 } 18 private: 19 static Mutex lock_; 20 static Singleton *instance_; A4 static Singleton *instance_test_; 21 }; 分析: 如果 instance_test_ == 0 则有可能instance_没有实例化、也有可能没有完全实例化、也有可能没有将new 的结果完全写入 instance,也有可能已经将new 的结果写入instance,但无论怎么样进入08--14代码都是没有问题的 如果instance_test_ != 0 即使flag_存在挥发性、写操作的非原子性,至少这个标志不为零时已经说明先前已经有代码走过第13行了,当然对象就已经生成并将对象结果写入instance_了。 很容易验证改进版本的Double Checked Locking 模式解决了前一模式带来的缺陷: (即使此时 instance_test_存在非原子性操作,可写操作的非原子性我们依然能够证明) 这里引入一个instance_test 的目的就是采用这个变量检测,这段代码是否已经走过某一段路经的原理,这里我把它叫做检测路经法吧(Checking Road)
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有