首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11:用于延迟初始化的安全双重检查锁定。有可能吗?

C++11:用于延迟初始化的安全双重检查锁定。有可能吗?
EN

Stack Overflow用户
提问于 2012-09-06 22:10:49
回答 2查看 5.2K关注 0票数 13

我读过很多关于线程安全双重检查锁定的问题(针对单例或惰性初始化)。在一些帖子中,答案是模式完全被打破了,其他人则提出了解决方案。

所以我的问题是:有没有一种方法可以用C++编写一个完全线程安全的双重检查锁定模式?如果是这样,它看起来是什么样子。

我们可以假设是C++11,如果这让事情变得更容易的话。据我所知,C++11改进了内存模型,可以产生所需的改进。

我知道,在Java中,通过使双重检查保护变量成为可变变量是可能的。由于C++11借用了大部分内存模型,所以我认为这是可能的,但如何实现呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-06 22:28:03

对于延迟初始化的单例,只需使用静态局部变量,如下所示:

代码语言:javascript
复制
MySingleton* GetInstance() {
  static MySingleton instance;
  return &instance; 
}

(C++11)标准已经保证了静态变量是以线程安全的方式初始化的,而且它的实现似乎至少和你自己编写的任何东西一样健壮和高性能。

初始化的线程安全性可以在(C++11)标准的§6.7.4中找到:

如果控件在初始化变量时并发进入声明,则并发执行应等待初始化完成。

票数 18
EN

Stack Overflow用户

发布于 2017-08-19 12:09:11

既然您希望看到一个有效的DCLP C++11实现,下面就是一个。

该行为是完全线程安全的,并且与Grizzly答案中的GetInstance()完全相同。

代码语言:javascript
复制
std::mutex mtx;
std::atomic<MySingleton *> instance_p{nullptr};

MySingleton* GetInstance()
{
    auto *p = instance_p.load(std::memory_order_acquire);

    if (!p)
    {
        std::lock_guard<std::mutex> lck{mtx};

        p = instance_p.load(std::memory_order_relaxed);
        if (!p)
        {
            p = new MySingleton;
            instance_p.store(p, std::memory_order_release);
        }
    }

    return p;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12302057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档