首页 > 代码库 > 单例模式并不简单
单例模式并不简单
你真的了解单例模式吗?
首先,如果你不知道什么是 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
如果我将来可以有幸成为一个面试官,我可能希望面试者写一个单例模式给我。
本文禁止转载,谢谢
单例模式并不简单