为多线程环境实现单例的内存泄漏


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

No.当 A 被中断时,它拥有锁。因此,B 必须等到 A 释放锁,但随后分配了 pInstance,B 对 null 的第二次检查将失败。

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

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

实现不得在执行初始值设定项。

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

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

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

最新更新