Потокобезопасный Синглтон класса


Я создал этот класс для моделирования потокобезопасный Синглтон.

Я ничего не упустил?

#include <boost/thread/mutex.hpp>

class Singleton
{
public:
  static Singleton& GetInstance()
  {
    boost::mutex::scoped_lock lock(m_mutex);
    static Singleton instance;
    return instance;
  }

private:
  static boost::mutex m_mutex;

  Singleton() {}
  ~Singleton() {}

  Singleton(const Singleton&);
  const Singleton& operator=(const Singleton&);
};


23565
21
задан 30 ноября 2011 в 08:11 Источник Поделиться
Комментарии
2 ответа

Как обычно, когда имеешь дело с одноплодной беременности, считают, что вы, вероятно, не следует делать синглтон на всех.

Читать этот, например. Одноэлементный это почти наверняка не то, что вам действительно нужно, даже если это сделано правильно и в потокобезопасным способом.

Простой старый глобальной может быть лучшим вариантом, или, возможно, вы должны просто передать ссылку на тех, кто в ней нуждается.

3
ответ дан 30 ноября 2011 в 09:11 Источник Поделиться

Статические m_mutex член не правильный синглтон себя. Вы не можете использовать этот синглтон в статических переменных инициализация потому что m_mutex не создается лениво и может быть не инициализирована.

Кроме того, это неправильно, чтобы положить логику в Синглтон класса, он должен быть шаблон класса.

#ifndef SINGLETON_H_689E0B11_E731_4555_AFE6_88598B582F1D
#define SINGLETON_H_689E0B11_E731_4555_AFE6_88598B582F1D

#include <cassert>
#include <boost/thread/mutex.hpp>

template<class T>
class Singleton
{
public:
static T& GetInstance()
{
assert(!is_destructed);
(void)is_destructed; // prevent removing is_destructed in Release configuration

boost::mutex::scoped_lock lock(GetMutex());
static T instance;
return instance;
}

private:
static bool is_destructed;

static boost::mutex& GetMutex()
{
static boost::mutex mutex;
return mutex;
}

Singleton() {}
~Singleton() { is_destructed = true; }
};

// force creating mutex before main() is called
template<class T>
bool Singleton<T>::is_destructed = (Singleton<T>::GetMutex(), false);

#endif // SINGLETON_H_689E0B11_E731_4555_AFE6_88598B582F1D

Так как это частная деструктор, это noncopyable - не нужно объявить конструктор копирования и копирующий оператор присваивания.

3
ответ дан 1 декабря 2011 в 09:12 Источник Поделиться