Oracle® Solaris Studio 12.4:线程分析器用户指南

退出打印视图

更新时间: 2014 年 12 月
 
 

使用双检锁的程序

单件可确保在整个程序中只有一个特定类型的对象存在。双检锁是在多线程应用程序中对单件进行初始化的一种常见的有效方法。以下代码将说明这样的实现。

100 class Singleton {
101     public:
102     static Singleton* instance();
103     ...
104     private:
105     static Singleton* ptr_instance;
106 };
107
108 Singleton* Singleton::ptr_instance = 0;
...

200 Singleton* Singleton::instance() {
201     Singleton *tmp;
202     if (ptr_instance == 0) {
203         Lock();
204         if (ptr_instance == 0) {
205             tmp = new Singleton;
206
207             /* Make sure that all writes used to construct new
208                Singleton have been completed. */
209             memory_barrier();
210
211             /* Update ptr_instance to point to new Singleton. */
212             ptr_instance = tmp;
213
214         }
215         Unlock();
216     }
217     return ptr_instance;

ptr_instance 的读取(第 202 行)特意未用锁进行保护。这样就可以通过检查来确定 Singleton(单件)是否已经在多线程环境中进行有效实例化。请注意,第 202 行的读取与第 212 行的写入之间存在对变量 ptr_instance 的数据争用,但程序可正常工作。不过,编写允许数据争用的正确程序时,需要格外小心。例如,在以上双检锁定代码中,第 209 行中对 memory_barrier() 的调用用来确保线程不会看到 ptr_instance 为非空,直至构造 Singleton(单件)的所有写入已完成。