Дата отображается в GMT: 2012-02-29 00:00:00 +0000
- 2012-03-01 22:00:00 +0200
. Также не забудьте изменить время перехода на летнее время, что объясняет, почему вы иногда получаете разницу в 3 часа.
Дата результата верна, но отладчик отображает ее в GMT.
Если Вы, используют Visual C++ 2005/2008, можно использовать проверенный дважды шаблон блокировки, с тех пор" , энергозависимые переменные ведут себя как заборы ". Это - самый эффективный способ реализовать лениво инициализированный одиночный элемент.
Singleton* GetSingleton()
{
volatile static Singleton* pSingleton = 0;
if (pSingleton == NULL)
{
EnterCriticalSection(&cs);
if (pSingleton == NULL)
{
try
{
pSingleton = new Singleton();
}
catch (...)
{
// Something went wrong.
}
}
LeaveCriticalSection(&cs);
}
return const_cast<Singleton*>(pSingleton);
}
Каждый раз, когда Вам нужен доступ к одиночному элементу, просто назовите GetSingleton (). В первый раз, когда это называют, статический указатель будет инициализирован. После того, как это будет инициализировано, ПУСТАЯ проверка предотвратит блокировку для того, чтобы просто считать указатель.
НЕ ДЕЛАЮТ использование это на просто никаком компиляторе, поскольку это не портативно. Стандарт не делает гарантий о том, как это будет работать. Visual C++ 2005 явно добавляет к семантике энергозависимых для создания этого возможным.
необходимо будет объявить, и инициализируют КРИТИЧЕСКИЙ РАЗДЕЛ в другом месте в коде. Но та инициализация является дешевой, таким образом, ленивая инициализация обычно не важна.
Можно использовать ОС, примитивную, такую как взаимное исключение или критический раздел для обеспечения ориентированной на многопотоковое исполнение инициализации однако, это подвергнется издержкам каждый раз, когда одноэлементному указателю получают доступ (из-за получения блокировки). Это также не портативно.
Существует один проясняющий вопрос, который необходимо рассмотреть для этого вопроса. Вы требуете...
существует много образцов в сети для реализации этих шаблонов в C++. Вот Образец Проекта Кода
Следующее объясняет, как сделать это в C#, но то же самое понятие относится к любому языку программирования, который поддерживал бы шаблон "одиночка"
http://www.yoda.arachsys.com/csharp/singleton.html
, Что необходимо решить, хотите ли Вы ленивую инициализацию или нет. Ленивая инициализация означает, что объект, содержавший в одиночном элементе, создается на первом вызове к ней исключая:
MySingleton::getInstance()->doWork();
, если тот вызов не выполняется до позже, существует опасность состояния состязания между потоками, как объяснено в статье. Однако, если бы Вы помещаете
MySingleton::getInstance()->initSingleton();
в самом начале Вашего кода, где Вы предполагаете, что это было бы ориентировано на многопотоковое исполнение, тогда Вы больше не ленивая инициализация, Вы еще потребуете "немного" вычислительная мощность, когда Ваше приложение запустится. Однако это решит много головных болей об условиях состязания, если Вы сделаете так.
Простой способ гарантировать межплатформенная ориентированная на многопотоковое исполнение инициализация одиночного элемента должна выполнить его явно (через вызов к статической функции членства на одиночном элементе) в основном потоке Вашего приложения прежде , Ваше приложение запускает любые другие потоки (или по крайней мере любые другие потоки, которые получат доступ к одиночному элементу).
Удостоверяющийся ориентированный на многопотоковое исполнение доступ к одиночному элементу тогда достигается обычным способом со взаимоисключающими разделами / критическими разделами.
Ленивая инициализация может также быть достигнута с помощью подобного механизма. Обычная проблема, с которой встречаются с этим, состоит в том, что взаимное исключение, необходимое для обеспечения потокобезопасности, часто инициализируется в самом одиночном элементе, который просто продвигает проблему потокобезопасности к инициализации взаимоисключающего раздела / критического раздела. Один способ преодолеть эту проблему состоит в том, чтобы создать и инициализировать взаимоисключающий раздел / критический раздел в основном потоке Вашего приложения тогда передают его одиночному элементу через вызов к статической функции членства. Тяжелая инициализация одиночного элемента может тогда произойти ориентированным на многопотоковое исполнение способом с помощью этого предварительно инициализированного взаимного исключения / критического раздела. Например:
// A critical section guard - create on the stack to provide
// automatic locking/unlocking even in the face of uncaught exceptions
class Guard {
private:
LPCRITICAL_SECTION CriticalSection;
public:
Guard(LPCRITICAL_SECTION CS) : CriticalSection(CS) {
EnterCriticalSection(CriticalSection);
}
~Guard() {
LeaveCriticalSection(CriticalSection);
}
};
// A thread-safe singleton
class Singleton {
private:
static Singleton* Instance;
static CRITICAL_SECTION InitLock;
CRITICIAL_SECTION InstanceLock;
Singleton() {
// Time consuming initialization here ...
InitializeCriticalSection(&InstanceLock);
}
~Singleton() {
DeleteCriticalSection(&InstanceLock);
}
public:
// Not thread-safe - to be called from the main application thread
static void Create() {
InitializeCriticalSection(&InitLock);
Instance = NULL;
}
// Not thread-safe - to be called from the main application thread
static void Destroy() {
delete Instance;
DeleteCriticalSection(&InitLock);
}
// Thread-safe lazy initializer
static Singleton* GetInstance() {
Guard(&InitLock);
if (Instance == NULL) {
Instance = new Singleton;
}
return Instance;
}
// Thread-safe operation
void doThreadSafeOperation() {
Guard(&InstanceLock);
// Perform thread-safe operation
}
};
Однако существуют серьезные основания избежать использования одиночных элементов в целом (и почему они иногда упоминаются как антишаблон ):
, альтернатива должна использовать 'логический одиночный элемент', посредством чего Вы создаете и инициализируете единственный экземпляр класса в основном потоке и передаете его объектам, которые требуют его. Этот подход может стать громоздким, где существует много объектов, которые Вы хотите создать как одиночные элементы. В этом случае разрозненные объекты могут быть связаны в единственный объект 'Контекста', который тогда роздан в случае необходимости.
При поиске более портативного, и более легкого решения Вы могли бы обратиться к повышению.
повышение:: call_once может использоваться для ориентированной на многопотоковое исполнение инициализации.
Его довольно простое для использования, и будет часть следующего C++ 0x стандарт.
Существует много способов сделать ориентированную на многопотоковое исполнение Singleton* инициализация на окнах. На самом деле некоторые из них являются даже межплатформенными. В ТАК поток, с которым Вы связались, они искали Singleton, которая лениво создается в C, который немного более конкретен, и может быть немного более хитрым, чтобы сделать правильно, учитывая запутанность модели памяти, под которой Вы работаете.