C++;单身人士—;不完全C++;11标准 我努力在C++中设计一个线程安全的单线程实现,但是它主要针对Visual Studio 2012环境。 我知道C++ 11标准保证了这个< /P> Foo& Instance() { static Foo instance; return instance; }

C++;单身人士—;不完全C++;11标准 我努力在C++中设计一个线程安全的单线程实现,但是它主要针对Visual Studio 2012环境。 我知道C++ 11标准保证了这个< /P> Foo& Instance() { static Foo instance; return instance; },c++,singleton,C++,Singleton,是线程安全的。但是VisualStudio 2012中使用的编译器还没有完全符合C++ 11标准(至少关于静态变量初始化的线程安全性)。所以我想到了这个: #include <iostream> #include <atomic> #include <mutex> class Foo { public: static Foo& Instance(); private: Foo() { init();

是线程安全的。但是VisualStudio 2012中使用的编译器还没有完全符合C++ 11标准(至少关于静态变量初始化的线程安全性)。所以我想到了这个:

#include <iostream>
#include <atomic>
#include <mutex>

class Foo
{
    public:
        static Foo& Instance();

    private:
        Foo() { init(); }
        Foo(Foo const&);
        void operator = (Foo const&);
        void init() { std::cout << "init done." << std::endl; }
        static std::atomic<Foo*> _instance;
        static std::mutex _mutex;
};

std::atomic<Foo*> Foo::_instance = nullptr;
std::mutex Foo::_mutex;

Foo& Foo::Instance()
{
    if(_instance.load() == nullptr)
    {
        std::lock_guard<std::mutex> lock(_mutex);

        if(_instance.load() == nullptr)
        {
            _instance = new Foo();
        }
    }

    return *_instance;
}
#包括
#包括
#包括
福班
{
公众:
静态Foo&实例();
私人:
Foo(){init();}
Foo(Foo const&);
void运算符=(Foo const&);

void init(){std::cout双重检查锁定不是线程安全的。请参阅

与上述文章中的建议解决方案不同的替代解决方案:

T& thread_safe()
{
  static std::once_flag once;
  static T* result;
  struct Initialize
  {
    static void apply(T*& result) { result = new T; }
  };
  std::call_once(once, Initialize::apply(result);
  return *result;
}
注:

  • 如果您没有std::call_one,您可以求助于boost等价物
  • 您可以使用lambda,而不是使用本地结构
  • 如问题中所述,没有必要使用符合C++11标准的编译器

在,您可以找到一篇关于该主题的优秀论文,包括一些简单的现成示例。您的代码与上一个类似,但可能不正常,因为您没有使用
.store()
方法将指针复制到新创建的实例。它也可能不会生成最佳的机器指令。

这是旧的单例反模式。在检查单例是否仍然为空之前,必须锁定互斥体。你说得对,谢谢。我想我们应该在实际测试
if(\u instance.load()之前锁定互斥体==nullptr)
我们是安全的,对吗?但是不是
std::once_标志
C++11?在这种情况下,原始代码不是安全的吗?@Galik使用std::once_标志来确保线程安全的初始化不同于静态变量初始化(根据C++11,线程安全,但在msvc 2013中不安全)侧注:一个不错的链接