C ++ singleton - not a complete C ++ 11 standard

I'm struggling to develop a thread-safe singleton implementation in C ++, but it will focus primarily on Visual Studio 2012.

I know that the C ++ 11 standard ensures that this

Foo& Instance()
{
    static Foo instance;

    return instance;
}

is thread safe. But the compiler used in Visual Studio 2012 does not yet fully comply with the C ++ 11 standard (at least with respect to thread safety for initializing static variables). So I came up with this:

#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;
}

I would like to ask:

1) Is this code safe?

2) Is this code OK?

+4
source share
2 answers

. . http://mortoray.com/2012/02/28/double-checked-locking-why-doesnt-it-work-and-how-to-fix-it/

, :

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, .
  • lambda.
  • , , , ++ 11.
+2

​​ ++ 11, , . , , , , .store() . , .

+1

Source: https://habr.com/ru/post/1583821/


All Articles