Простой C ++ logger с использованием шаблона синглтона - PullRequest
6 голосов
/ 09 ноября 2009

Из-за примеров затопления реализации регистратора с использованием шаблона Singleton я только что написал простой регистратор C ++ в том же подходе для моей программы. Тем не менее, поскольку известный подход с двойной проверкой блокировки, как известно, не является более поточно-ориентированным, мне интересно, должен ли я:

1) Забудьте об использовании шаблона Singleton в этом случае?

2) Продолжать использовать двойную проверку блокировки, хотя это небезопасно?

3) Использовать дорогой метод чистой синхронизации для каждого доступа к его общедоступным интерфейсам?

Есть предложения?

Ответы [ 4 ]

16 голосов
/ 09 ноября 2009

Используйте Meyers Singleton. Если вы используете gcc, по крайней мере инициализация является поточно-ориентированной.

class Singleton{
   Singleton(){
    //This is threadsafe in gcc, no mutex required
   }
   static Singleton * instance(){
      static Singleton myinstance;
      return &myinstance;
   }
};

gcc защищает создание статических локальных компьютеров, если вы не отключите с помощью -fno-threadsafe-statics, я недавно писал об этом здесь

1 голос
/ 09 ноября 2009

Один из подходов состоит в том, чтобы убедиться, что ваш первый доступ к регистратору происходит до того, как ваше приложение запускает второй поток. Получая доступ к синглтону в то время, когда вы ЗНАЕТЕ, что нет никаких конфликтов, вы гарантируете, что последующие обращения всегда найдут уже существующий объект, и вам следует полностью избежать этой проблемы.

1 голос
/ 09 ноября 2009

В приложениях с потоками я предпочитаю использовать синглтоны с функцией initialize () и заявляет, чтобы убедиться, что initialize () используется до первого instance (). Вызовите initialize () из основного потока. Я не думаю, что ленивая реализация действительно ключевая особенность синглтона, особенно для регистратора.

Несмотря на то, что ответ Аркайца более элегантный, мои ответы позволяют избежать проблем с многопоточностью на всех платформах за счет затрат на одну дополнительную функцию и некоторых проблем, возникающих при создании экземпляра при запуске для синглтонов с зависимостями (с помощью утверждений и конечно: используйте синглтоны разумно).

0 голосов
/ 09 ноября 2009

Вам на самом деле не нужна отдельная функция Initialize (), так как это просто загрязнит ваш одноэлементный интерфейс. Просто получите экземпляр синглтона

VERIFY(NULL != Logger::Instance()); 

до того, как любой другой поток получит к нему доступ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...