随笔- 31  评论- 100  文章- 2 

单例模式并不简单

你真的了解单例模式吗?

首先,如果你不知道什么是 code arranger ,编译器指令重排技术,你对单例理解太肤浅。

其次,如果你不知道什么是 Out of Order Execution,处理器执行乱序技术,你对单例的理解还是有些浅薄。

最后,如果你不知道什么是 memory barrier,内存屏障技术,你对单例理解有待提高。

 

简单介绍:

编译器和CPU都有可能,打乱代码的运行顺序。所以 DCLP (Double Check)is broken,具体分析请看参考文献最后一篇。

老的C++编译器,volatile关键字只能确保在单线程,编译出来的代码拥有正确的顺序。

一旦使用第三方多线程库,编译器可能错误的优化第三方的代码,有或者引入多线程代码编译器无法严格volatile语义,即便加入volatile也无济于事。

即便在你的平台可以保持正确的行为,那么程序变得不可移植!更何况CPU也有可能乱序执行。

最终的解决方案是引入 ,内存栅栏技术,虽然可以正确的解决问题,但不可移植。

非常幸运,好在C++11 引入了语言级别的内存模型,提供标准的内存栅栏技术。内存栅栏是什么,请看参考文献。

还有哪些问题?

而实际上出来我介绍的这一点,单例间相互引用问题,衍生出,初始化顺序问题,以及销毁顺序问题,资源(内核对象,数据库连接等)泄露问题。

 

总结:

单例模式,是否是最简单的设计模式?很多国内书籍(甚至国外)讲解单例模式时草草了之,让我们误以为单例模式仅仅如此而已。世界上没有什么事情那么简单,只是我们研究的太浅显。

 

提供一下参考文献,供参考

Weak vs. Strong Memory Models

The Happens-Before Relation

Acquire and Release Fences

Double-Checked Locking Is Fixed In C++11

Double check is broken

 

如果我将来可以有幸成为一个面试官,我可能希望面试者写一个单例模式给我。

 

本文禁止转载,谢谢

 

posted on 2015-01-19 13:29  RonTang  阅读(793)  评论(5编辑  收藏