0
Singleton* Singleton::instance() {

if (pInstance == 0) {

    Lock lock;

    if (pInstance == 0) {

        Singleton* temp = new Singleton; // initialize to temp
        pInstance = temp; // assign temp to pInstance
   }
  }

假设编译器没有优化冗余温度。线程A在分配构造了Singleton对象,该对象由temp指向。现在 A 在那之后就被抢占了。现在线程 B 获得了锁,进入并检查 pInstance 是否为 NULL。它还将创建 Singleton 对象并覆盖现有指针。我想现在有内存泄漏。你有什么意见 ?完整的源代码在这里:代码参考:http ://erdani.com/publications/DDJ_Jul_Aug_2004_revised.pdf

4

2 回答 2

1

不,当 A 被中断时,它仍然拥有锁。因此 B 必须等到 A 释放锁,然后分配 pInstance 并且 B 对 null 的第二次检查将失败。

于 2013-10-11T19:25:14.907 回答
1

在 C++11 中,该标准在第 6.7 段中规定:

这样的变量在控制第一次通过其声明时被初始化;这样的变量在其初始化完成时被认为已初始化。[...]如果在初始化变量时控制同时进入声明,则并发执行应等待初始化完成。

实现不得在初始化程序的执行周围引入任何死锁。

这导致以下非常简单且线程安全的单例方法实现:

Singleton* Singleton::instance() {
    Singleton instance;
    return &instance;
}

有关哪些编译器支持此功能的更多详细信息,请参阅此问题

于 2013-10-12T13:38:49.883 回答