使用 std::call_once 创建 singleTon 类

Posted

技术标签:

【中文标题】使用 std::call_once 创建 singleTon 类【英文标题】:create singleTon class using std::call_once 【发布时间】:2019-08-09 16:01:28 【问题描述】:

以下代码是在C++11 中使用std::call_once 的替代singleTon 类的实现。基本上,变量static_instancestatic_flag 一起静态声明,一旦调用getInstance 函数(也是静态函数),我使用call_once 创建mySingle 的第一个也是唯一一个实例。

我很高兴听到任何 cmets 关于线程安全方面的代码正确性,以及它的行为是否不同于在 getinstance 中定义静态变量的标准 C++ 实现。

mySingle.h

class mySingle

    static mySingle *static_instance;
    static std::once_flag static_flag;
public:

    mySingle();
    virtual ~mySingle();
    static mySingle* getInstance();
;

mySingle.cpp

#include "mySingle.h"

mySingle * mySingle::static_instance;
std::once_flag mySingle::static_flag;

mySingle::mySingle()
mySingle::~mySingle()

mySingle* mySingle::getInstance()

    std::call_once(g_flag, [&]()  static_instance = new mySingle(); );
    return (mySingle*) static_instance;

【问题讨论】:

第一个想法是乱七八糟的 - 你为什么要把像典型的静态变量单例一样简单的事情复杂化? 原因是在windows中(至少这是我检查过的),标准实现使用对线程本地存储的访问(如果你反汇编编译的代码,你会看到对寄存器gs:[58h]的访问这是 TLS。我希望避免这种情况。 看这篇文章:modernescpp.com/index.php/thread-safe-initialization-of-data,看看 scott meyers singleton @Gojita,很棒的文章,谢谢! 【参考方案1】:

来自std c++ call_once,它说

只执行一次 Callable 对象 f,即使是从多个线程并发调用。

所以人们会期望这是线程安全的

【讨论】:

以上是关于使用 std::call_once 创建 singleTon 类的主要内容,如果未能解决你的问题,请参考以下文章

如何确保 std::call_once 真的只被调用一次

C++ 11 call_once

C++ 11 call_once

在抛出 'std::system_error' 的实例后调用终止

线程安全的对象生命期管理

双重检查锁定的正确编译器内在函数?