Singleton(Получение-Освобождение семантики)

Пользователь
Статус
Оффлайн
Регистрация
28 Апр 2018
Сообщения
134
Реакции[?]
35
Поинты[?]
0
Код:
#include <atomic>
#include <iostream>
#include <future>
#include <mutex>
#include <thread>
template<typename T>
class Singleton
{
protected:
Singleton() {}
~Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(Singleton&&) = delete;
private:
static std::atomic<T> instance;
static std::mutex Mutex;
public:
static T& Get()
{
T inst = instance.load(std::memory_order_acquire);
if ( !inst )
{
std::lock_guard<std::mutex> Lock(Mutex);
inst = instance.load(std::memory_order_relaxed);
if( !inst )
{
inst = new Singleton();
instance.store(inst,std::memory_order_release);
}
}
return inst;
}
};
Этот синглтон более сложный, но в тоже время и быстрый, он быстрее благадоря освобождению атома.
Описание работы синглтона:
Чтение синглтона - операция получения, запись, операции деблокирования(14 и 20 строка). Поскольку обе операции происходят на одном и том же атоме, мне не нужна последовательная согласованность. Стандарт C++ гарантирует, что операция получения синхронизируется с операцией освобождения на том же атоме. В этом случае эти условия сохраняются, поэтому я могу ослабить модель памяти C++ в строках 14 и 20. Достаточно получить семантику получения-освобождения.
Семантика получения-выпуска имеет такую же производительность, как и последовательная согласованность. Это неудивительно, потому что на x86 обе модели памяти очень похожи.
 
Пользователь
Статус
Оффлайн
Регистрация
23 Сен 2016
Сообщения
239
Реакции[?]
47
Поинты[?]
0
Это конечно очень круто(да?) Но не расскажешь,где это используется ?
 
Я лучше тебя
Участник
Статус
Оффлайн
Регистрация
31 Июл 2017
Сообщения
383
Реакции[?]
448
Поинты[?]
1K
Это конечно очень круто(да?) Но не расскажешь,где это используется ?
это для многопоточных приложений полезно. Если глобальный указатель на класс будет использоваться в более чем 1 потоке
 
Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
991
Реакции[?]
1,209
Поинты[?]
3K
Код:
 class YouClass : public Singleton<YouClass> {
     friend class Singleton<YouClass>;
public:
      YouClass(){
       }
      ~YouClass(){
       }
       void CallFun(){
       printf_s("Call");
       }
     };
   
   
     Ex:
     YouClass::Get()->CallFun();

ЗЫ: есть такая замечательная приблуда, как: std::forward<>. Можно здорово разнообразить данный метод, который позволить передавать конструктору динамическое количество параметров))
 
Пользователь
Статус
Оффлайн
Регистрация
28 Апр 2018
Сообщения
134
Реакции[?]
35
Поинты[?]
0
Код:
 class YouClass : public Singleton<YouClass> {
     friend class Singleton<YouClass>;
public:
      YouClass(){
       }
      ~YouClass(){
       }
       void CallFun(){
       printf_s("Call");
       }
     };
  
  
     Ex:
     YouClass::Get()->CallFun();

ЗЫ: есть такая замечательная приблуда, как: std::forward<>. Можно здорово разнообразить данный метод, который позволить передавать конструктору динамическое количество параметров))
ну да + если туда добавить std::function и std::bind и вызывать интернал инстенс не херово получится, методов реалазиаций синглтона дохуя, я думал ты прилетишь и будешь мне пизды давать за этот код
 
Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
991
Реакции[?]
1,209
Поинты[?]
3K
std::function и std::bind
а зачем тут это? что-то я не могу представить где это могло бы использоваться.

а так любой умный указатель + std::forward. Хотя можно и без указателя обойтись, но лучше с ним, так как он сам будет "следить" за памятью.
 
Пользователь
Статус
Оффлайн
Регистрация
28 Апр 2018
Сообщения
134
Реакции[?]
35
Поинты[?]
0
а зачем тут это? что-то я не могу представить где это могло бы использоваться.

а так любой умный указатель + std::forward. Хотя можно и без указателя обойтись, но лучше с ним, так как он сам будет "следить" за памятью.
пример
Код:
template<typename T>
class Singleton
{
protected:
Singleton() = default; 
Singleton( const Singleton& ) = delete;
Singleton& operator=( const Singleton& ) = delete;
virtual ~Singleton() = default; 
public:    
template<typename... Args>
static T& Get( Args... args )  
 { static auto onceFunction = std::bind(CreateInternalIntance<Args...>, args... );
return ApplyFunction(onceFunction);
}
private:
static T& ApplyFunction(const std::function<T&()>& function )   
{ static T& instance = function();  
 return instance;    
}    
template<typename... Args>
static T&
CreateInternalIntance(Args... args ) 
{
static T instance{std::forward<Args>( args )... };        
return instance;
}
};
 
Сверху Снизу