Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Dependency Injection, маловато инфы в рунете 
:(
    Опции темы
Леопольд
Дата 13.8.2010, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(SABROG @  13.8.2010,  11:37 Найти цитируемый пост)
Во первых мутекс блокирует работу всех остальных потоков, которые пытаются получить доступ к синглтону, а могли бы делать полезную работу. Если дальше копать, то там нужен второй мутекс, а потом в итоге и он не спасает, погугли на "Double Checked Locking Broken".
Блокирует только если инстанс не создан и до тех пор, пока он не будет создан целиком, иначе просто возвращает указатель без блокировки.



--------------------
вопросов больше чем ответов
PM MAIL   Вверх
SABROG
Дата 13.8.2010, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Цитата(Леопольд @  13.8.2010,  12:30 Найти цитируемый пост)
Блокирует только если инстанс не создан и до тех пор, пока он не будет создан целиком, иначе просто возвращает указатель без блокировки.

Фиг с ней с этой блокировкой, там причина в многократной инициализации одного и того же синглтона в разных потоках.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Леопольд
Дата 13.8.2010, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(SABROG @  13.8.2010,  12:45 Найти цитируемый пост)
там причина в многократной инициализации одного и того же синглтона в разных потоках.
Цитата(SABROG @  13.8.2010,  12:45 Найти цитируемый пост)
Блокирует ... до тех пор, пока он не будет создан целиком



Это сообщение отредактировал(а) Леопольд - 13.8.2010, 13:24


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
SABROG
Дата 13.8.2010, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Цитата(Леопольд @  13.8.2010,  13:23 Найти цитируемый пост)
Блокирует ... до тех пор, пока он не будет создан целиком

Это относится к одному потоку. Каждый поток будет создавать целиком по своей копии. На уровне компилятора тут нет синхронизации.

Не забывай и про такую ситуацию:

Код

m_instance = new MySingleton; 
// под объект выделяется память и указатель присваивается m_instance
// затем другой поток прерывает работу этого потока еще до того как он успеет вызвать конструктор
// другой поток видит, что указатель существует, т.е. объект создан и пытается с ним работать
// а объект синглтона не валиден по той простой причине, что конструктор еще не вызывался



--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
boostcoder
Дата 13.8.2010, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(SABROG @  13.8.2010,  11:37 Найти цитируемый пост)
в функции boost::callonce()

Цитата(SABROG @  13.8.2010,  11:37 Найти цитируемый пост)
Но это мне не подходит, так как я пока не хочу тянуть boost, да еще и ради антипаттерна.

ради call_once() boost тащить не надо. она есть во всех свежих версиях компиляторов.

Добавлено через 1 минуту и 56 секунд
SABROG, мешанина какая-то в теме..
в данный момент, как я понял, проблема в инициализации синглтона? или в чем?

Добавлено через 2 минуты и 40 секунд
Цитата(boostcoder @  13.8.2010,  13:34 Найти цитируемый пост)
она есть во всех свежих версиях компиляторов.

по моему, она есть даже в Qt.
PM WWW   Вверх
SABROG
Дата 13.8.2010, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Цитата(boostcoder @  13.8.2010,  13:34 Найти цитируемый пост)
она есть во всех свежих версиях компиляторов.

Она есть только в стандарте C++0x. Я конечно не консерватор, но стандарт еще не принят и хочется переносимости на старые компиляторы.

Цитата(boostcoder @  13.8.2010,  13:34 Найти цитируемый пост)
в данный момент, как я понял, проблема в инициализации синглтона? или в чем?

Сейчас мне интересно мнение насчет варианта без синглтона, варианта, который используется в нескольких проектах, которые я обнаружил через google/codesearch. То есть разновидность глобальных указателей:
Код

// .h
class EditorManager
{
public:
    EditorManager()
    {
         m_instance = this;
    }
    static EditorManager* instance() {return m_instance;}
private:
    static EditorManager* m_instance;
};
...
// .cpp
static EditorManager::m_instance = 0;
...
// main.cpp
int main(int argc, char* argv[])
{
    EditorManager em; // создание экземпляра одиночки
    doStuff();
    ...
}


Цитата(boostcoder @  13.8.2010,  13:34 Найти цитируемый пост)
по моему, она есть даже в Qt. 

Нету, я писал свою реализацию при помощи Дмитрия Вьюкова (специалиста по конкурентному программированию).


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Леопольд
Дата 13.8.2010, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(SABROG @  13.8.2010,  13:31 Найти цитируемый пост)
// другой поток видит, что указатель существует, т.е. объект создан и пытается с ним работать
// а объект синглтона не валиден по той простой причине, что конструктор еще не вызывался
Спасибо. Упустил этот момент.

Добавлено @ 14:12
Цитата(SABROG @  13.8.2010,  13:46 Найти цитируемый пост)
Сейчас мне интересно мнение насчет варианта без синглтона, варианта, который используется в нескольких проектах, которые я обнаружил через google/codesearch. То есть разновидность глобальных указателей:
Хорошо сочетается с принципом KISS smile


Это сообщение отредактировал(а) Леопольд - 13.8.2010, 14:13


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 13.8.2010, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(SABROG @  12.8.2010,  20:44 Найти цитируемый пост)
. Напрашивается синглтон, но мы знаем, что это антипаттерн и поэтому он быстро "распрашивается" обратно

не читал, темы, но для доступа к настройкам имхо уже есть _синглетон_ приложения , который можно использовать. (наследник QApp в вашем случае ) smile


--------------------
PM MAIL WWW   Вверх
SABROG
Дата 13.8.2010, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Цитата(mes @  13.8.2010,  14:50 Найти цитируемый пост)
наследник QApp в вашем случае

Вопрос задавался в контексте языка C++, а не конкретного фреймворка. А так то варианты есть.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Леопольд
Дата 13.8.2010, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(SABROG @  13.8.2010,  13:31 Найти цитируемый пост)
// другой поток видит, что указатель существует, т.е. объект создан и пытается с ним работать
// а объект синглтона не валиден по той простой причине, что конструктор еще не вызывался
Код

#include <boost/thread/mutex.hpp>

template<typename T>
struct Singleton{
    static T& instance(){
        if(!instance_){
            boost::mutex::scoped_lock lock(mutex_);
            if(!instance_)
                instance_ = create_();
        }
        return const_cast<T&>(*instance_);
    }
private:
    static volatile T* instance_;
    static boost::mutex mutex_;

    typedef T* (*FPtr) ();
    typedef volatile FPtr VFPtr;
    static VFPtr create_;
    static T* creator(){
        return new T();
    }
};
template<typename T>
volatile T* Singleton<T>::instance_ = 0;
template<typename T>
boost::mutex Singleton<T>::mutex_;
template<typename T>
typename Singleton<T>::VFPtr Singleton<T>::create_ = &Singleton<T>::creator;
smile 

Это сообщение отредактировал(а) Леопольд - 13.8.2010, 16:34


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 13.8.2010, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(SABROG @  13.8.2010,  15:20 Найти цитируемый пост)
Вопрос задавался в контексте языка C++, а не конкретного фреймворка. А так то варианты есть. 

1. суть не меняется... настройки это часть приложения, через него они и должны быть доступны..
2. синглетон не всегда антипаттерн. Антипаттерн  - применять синглетон без обдумывания.
дальнейшее зависит от задачи и фреймворка.


--------------------
PM MAIL WWW   Вверх
SABROG
Дата 13.8.2010, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Цитата(Леопольд @  13.8.2010,  16:33 Найти цитируемый пост)

Код

    static T* creator(){
        return new T();
    }


К сожалению не спасет от двух видов оптимизации. Одну делает компилятор, другую может делать линкер. Как получить гарантии того, что этих оптимизаций производиться не будет на всех известных компиляторах?

Как сказали бы Александреску с Мейерсом: "Game over. You lose." Почитай статью, чтобы не придумывать новых велосипедов.




--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Леопольд
Дата 13.8.2010, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(SABROG @  13.8.2010,  18:25 Найти цитируемый пост)
К сожалению не спасет от двух видов оптимизации. Одну делает компилятор, другую может делать линкер. Как получить гарантии того, что этих оптимизаций производиться не будет на всех известных компиляторах?
volatile указатель на функцию, и вызов функции через этот указатель.
Александреску конечно умный мужик, но это не повод унывать...  smile 

Код
    typedef T* (*FPtr) ();
    typedef volatile FPtr VFPtr;
    static VFPtr create_;
    ...
    template<typename T>
    typename Singleton<T>::VFPtr Singleton<T>::create_ = &Singleton<T>::creator;
    ...
    instance_ = create_();


Если есть какие-то сомнения, то можно заменить на виртуальный вызов через указатель на базовый класс. Наследника определить в другой единице трансляции, на всякий случай.

Это сообщение отредактировал(а) Леопольд - 13.8.2010, 18:50


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 13.8.2010, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(SABROG @  13.8.2010,  18:25 Найти цитируемый пост)
Почитай статью
Читал, где-то год назад. Вот ещё интересная статься под авторством Александреску. http://www.drdobbs.com/184403766;jsessioni...HPSKH4ATMY32JVN



--------------------
вопросов больше чем ответов
PM MAIL   Вверх
SABROG
Дата 13.8.2010, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Следом идет другая проблема - когерентность кеша. У каждого ядра/процессора своя копия данных памяти в кеше и когда один поток меняет данные (устанавливает указатель, инициализирует члены класса), то нужно об этом сообщать другим потокам, иначе у них останутся "старые" данные. То есть возникает необходимость добавлять барьеры памяти или использовать атомарные инструкции типа Acquire/Release, чтобы сообщать другим потокам, что чего-то изменилось и кеши нужно обновить. Стандартных механизмов сделать это в C++ нет. На данном этапе этот язык совершенно не подготовлен к конкурентному программированию. К счатью работа в этом направлении ведется и с новым стандартом мы получим полноценный набор атомарных методов.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Страницы: (4) Все 1 [2] 3 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1319 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.