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

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

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: Класс настроек  (Прочитано 21421 раз)
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #15 : Сентябрь 17, 2014, 11:43 »

Ну давайте копнем, что ли (а то много общих слов  Улыбающийся). Корректна ли такая реализация ?

Код
C++ (Qt)
MySingle * MySingle::mInstance = 0;
 
MySingle * MySingle::Instance( void )
{
static QMutex mutex;
if (!mInstance) {
 QMutexlocker lock(&mutex);
 mInstance = new MySingle;
}
return mInstance;
}
нет, реализация некорректна.
Записан
Bepec
Гость
« Ответ #16 : Сентябрь 17, 2014, 11:58 »

Приводите аргументы, вместо недоказанных утверждений, пожалуйста Улыбающийся

Замечу - фриз будет если вызывать instance раз 200-300 без перерыва. А на хорошей архитектуре он будет вызываться 1 раз при создании объекта.

update: Да. Некорректная реализация именно из-за блокировки после условия. Там вполне возможна аварийная ситуация при захвате и ожидании мутексов. Создадутся N копий синглтона. Но вынос блокировки наверх решает эту проблему Веселый
« Последнее редактирование: Сентябрь 17, 2014, 11:59 от Bepec » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #17 : Сентябрь 17, 2014, 12:01 »

Приводите аргументы, вместо недоказанных утверждений, пожалуйста Улыбающийся

Замечу - фриз будет если вызывать instance раз 200-300 без перерыва. А на хорошей архитектуре он будет вызываться 1 раз при создании объекта.


QMutex - это не POD, делать статик не-POD нельзя. Что будет, если 2 потока начнут инициализировать мьютекс? Можно заменить на QBasicMutex.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Сентябрь 17, 2014, 12:01 »

Хм, я бы поставил QMutexLocker перед if. А так, подозрений не вызывает)
Типа "да хз, вот так точно будет работать". Так-то оно так, но ведь захват мутекса - трудоемкая операция, а синглтон может зваться очень часто.

 
++ убрать перед if. На первый взгляд нормальная архитектурка.
Какими короткими стали Ваши ответы, куда же девалась обычная словоохотливость ?  Улыбающийся

А если так?
Код:
QScopedPointer<MySingle> MySingle::m_instance(new MySingle());
MySingle *MySingle::instance() {
    return m_instance.data();
}
Ну если объявлять его глобально (до main) - то и никакие scoped не нужны. Но такое объявление не всегда выгодно/возможно

А про стандарт с++11 кто-нить вообще слышал?  Подмигивающий
А без нового стандарта чего-то можем? Или тогда в дуст полезем?  Улыбающийся
Записан
Bepec
Гость
« Ответ #19 : Сентябрь 17, 2014, 12:05 »

Синглтон НЕ ДОЛЖЕН зваться часто. Он инициализироваться должен 1 (ОДИН) раз.
1 раз для каждой подгружаемой сущности. В результате количество вызовов синглтона должно быть равным количеству сущностей.

Фризов НЕ БУДЕТ.

А если он будет вызываться 60 раз в секунду - тогда голову надо пожмякать тому, кто напишет такую программу.

Ибо даже если самую простейщую операцию вызывать нонстоп - заглохнет всё.

PS вот тут и возникает ситуация о которой я писал - синглтон зависим от архитектуры. И вменяемости программиста.

update: Словоохотливость вкл.
Рассуждения о "трудоёмкости", "фризах" и прочем - это мифы. Те, кто утверждают что "синглтон будет вызываться часто" - видимо имеют случай "голова не знает что руки делают".

to Max: приведите пример синглтона с новым стандартом пожалуйста. Мне интересно.

to Аварон: настолько глубоко я мутексы и статик не знал, спасибо за пояснение.
Словоохотливость выкл.
« Последнее редактирование: Сентябрь 17, 2014, 12:09 от Bepec » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Сентябрь 17, 2014, 12:06 »

QMutex - это не POD, делать статик не-POD нельзя. Что будет, если 2 потока начнут инициализировать мьютекс? Можно заменить на QBasicMutex.
Есть опция "statics are thread-safe" культурно защищает инициализацию спыннером. Но вообще да, лучше не искать приключений и вынести mutex за тело ф-ции.

Но в том что я привел еще 2 пробоя. Первый детский, режет глаз. Второй - на мой взгляд логикой найти невозможно, тот печальный случай когда зубрилка побеждает (ну так иногда бывает  Улыбающийся)
Записан
Bepec
Гость
« Ответ #21 : Сентябрь 17, 2014, 12:10 »

Как обычно, Igors свёл рассуждение о синглтоне к поиску ошибок в куске левого кода Улыбающийся
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #22 : Сентябрь 17, 2014, 12:14 »

QMutex - это не POD, делать статик не-POD нельзя. Что будет, если 2 потока начнут инициализировать мьютекс? Можно заменить на QBasicMutex.
Есть опция "statics are thread-safe" культурно защищает инициализацию спыннером. Но вообще да, лучше не искать приключений и вынести mutex за тело ф-ции.

Но в том что я привел еще 2 пробоя. Первый детский, режет глаз. Второй - на мой взгляд логикой найти невозможно, тот печальный случай когда зубрилка побеждает (ну так иногда бывает  Улыбающийся)


Не во всех комиляторах. В гцц вышеприведенный код и без всяких опций будет работать, что не означает, что он верен.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #23 : Сентябрь 17, 2014, 12:21 »

[Не во всех комиляторах. В гцц вышеприведенный код и без всяких опций будет работать, что не означает, что он верен.
Ладно, чтобы "сердце успокоилось" исправляем

Код
C++ (Qt)
MySingle * MySingle::mInstance = 0;
static QMutex mutex;
 
MySingle * MySingle::Instance( void )
{
if (!mInstance) {
 QMutexlocker lock(&mutex);
 mInstance = new MySingle;
}
return mInstance;
}
Теперь верно ?
Записан
OKTA
Гость
« Ответ #24 : Сентябрь 17, 2014, 12:31 »

Код:
MySingle * MySingle::mInstance = 0;
static QMutex mutex;
 
MySingle * MySingle::Instance( void )
{
 if (!mInstance) {
  QMutexlocker lock(&mutex);
  if (!mInstance) {
    mInstance = new MySingle;
  }
 }
 return mInstance;
}

Ну, можно еще так, с двойной проверкой для двойного успокоения сердца
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #25 : Сентябрь 17, 2014, 12:32 »

начали за здравие...

для "синглтонов" в Qt можно использовать Q_GLOBAL_STATIC

хорошее описание синглтонов есть в книге Александреску
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Сентябрь 17, 2014, 12:44 »

Код:
MySingle * MySingle::mInstance = 0;
static QMutex mutex;
 
MySingle * MySingle::Instance( void )
{
 if (!mInstance) {
  QMutexlocker lock(&mutex);
  if (!mInstance) {
    mInstance = new MySingle;
  }
 }
 return mInstance;
}

Ну, можно еще так, с двойной проверкой для двойного успокоения сердца
Не "можно", а обязательно так. Но, к сожалению, это все-таки неверно (по крайней мере для всех компиляторов)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #27 : Сентябрь 17, 2014, 13:01 »

для "синглтонов" в Qt можно использовать Q_GLOBAL_STATIC
Так это то же самое малодушное решение Верес'а (вынос блокировки вверх) - с той лишь разницей что используется атомарный локер
Записан
Bepec
Гость
« Ответ #28 : Сентябрь 17, 2014, 13:07 »

Ххы. Самый смак в том, что вашего идеального решения не существует, увы. А малодушное решение работать будет.
Записан
vizir.vs
Гость
« Ответ #29 : Сентябрь 17, 2014, 13:15 »

http://habrahabr.ru/post/150276/
Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


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