Russian Qt Forum
Ноябрь 23, 2024, 15:02 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Синглтон Маерса Thread Safe?  (Прочитано 4540 раз)
CuteBunny
Гость
« : Февраль 28, 2012, 15:23 »

Здравствуйте!

Недавно понял, что ничего не знаю в принципе об паттерне "одиночка"... Может даже вообще ничего не знаю?... Непонимающий

Начал читать кучу книг, особенно заинтересовала "Современное проектирование С++ Александреску"...

Взял из пример одиночку Маерса, т.к. мне понравилось, что не надо заботится об утечках, добавил пару своих функций и пытаюсь теперь понять на сколько оно thread-safe...

Собрал у себя следующее приложение:

Код:
#include <Windows.h>
#include <process.h>
#include <iostream>
#include <fstream>

class CNetworkLog
{
std::ofstream m_file;
CNetworkLog() {
InitializeCriticalSection(&m_cs);
m_file.open("nlog.txt", std::ios::app);
};
~CNetworkLog() {
DeleteCriticalSection(&m_cs);
m_file.close();
};
CNetworkLog(const CNetworkLog &clone) {};
CNetworkLog& operator=(CNetworkLog &rhv){};
CRITICAL_SECTION m_cs;
public:
static CNetworkLog& getInstance() {
static CNetworkLog instance;
return instance;
};
void WriteLog(const char * msg) {
EnterCriticalSection(&m_cs);
m_file << msg << std::endl;
LeaveCriticalSection(&m_cs);
}
};

unsigned int __stdcall threadFunc(void *args)
{
CNetworkLog &log = CNetworkLog::getInstance();
log.WriteLog("test");
_endthreadex(0);
return 0;
}

int main()
{
const int max = 100;
HANDLE hHandles[max];
for (int i = 0; i < max; ++i) {
hHandles[i] = (HANDLE)_beginthreadex(NULL, 0, &threadFunc, NULL, 0, 0);
}
WaitForMultipleObjects(max, hHandles, TRUE, INFINITE);
for (int i = 0; i < max; ++i) {
CloseHandle(hHandles[i]);
}
return 0;
}

Конфигурация компьютера: i5-2300 2.8GHZx2, Win7 x86
Собирал на VS2010.

Где-то в интернете я прочитал, что одиночка Маерса не thread-safe и нужно применить синхронизацию при создании экземпляра...

В принципе у меня все работает, но правильно ли?

« Последнее редактирование: Февраль 28, 2012, 15:26 от CuteBunny » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Февраль 28, 2012, 20:36 »

Код:
	static CNetworkLog& getInstance() {
static CNetworkLog instance;
return instance;
};
Проще объявить instance в классе. А так (внутри метода) корректность зависит от установки компилятора "statics are thread-safe" (ключ не помню). Если она вкл то вызов конструктора статика будет защищен спином, иначе возможны неприятности
Записан
CuteBunny
Гость
« Ответ #2 : Февраль 29, 2012, 09:07 »

Ок, спс.

Почитал еще тут в msdn про статические переменные:

Цитировать
Assigning a value to a static local variable in a multithreaded application is not thread safe and we do not recommend it as a programming practice.

Раз микрософт не рекомендует так делать, значит так не стоит делать Улыбающийся

Цитировать
To cite §3.6 of C++11 "Declaration statement [stmt.dcl]":
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
So if assigning a value to a static local variable is not thread-safe in Visual C++, the compiler is violating the official C++ spec.

Хммм, может они в новой версии сделают cl по новому стандарту и тогда можно будет не париться.
« Последнее редактирование: Февраль 29, 2012, 09:11 от CuteBunny » Записан
niXman
Гость
« Ответ #3 : Март 04, 2012, 10:56 »

Цитировать
Синглтон Маерса Thread Safe?
нет.
три самых популярных синглтона: http://forum.try-catch.ru/topic_1039_0.html
Записан
SASA
Гость
« Ответ #4 : Март 05, 2012, 12:13 »

три самых популярных синглтона: http://forum.try-catch.ru/topic_1039_0.html
The requested URL /topic_1039_0.html was not found on this server.  Плачущий
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.048 секунд. Запросов: 22.