Re[2]: [Trick] Упгрейд для синглтона
От: AndrewJD США  
Дата: 29.08.07 13:26
Оценка:
Здравствуйте, _uncle, Вы писали:

R>>Вот подумалось.

_>Настоящий программист должен сделать две вещи: определить NULL и написать самую крутую реализацию Singleton'а.

Еще он должен написать свой класс строк.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[6]: Гибрид
От: Ivan Россия www.rsdn.ru
Дата: 29.08.07 14:15
Оценка:
Здравствуйте, remark, Вы писали:

R>Что конкретно ты имеешь в виду?

R>Ленивость Синглтона Мейерса гарантирует создание до первого обращения.
R>С разрушением правда хуже. Но зачастую такие синглтоны можно и не рушить вообще. Если, речь идёт, например, об инициализации какой-то таблицы, или открытии файла.

вот цитата из той ветки:

// Furthermore, since the instance() function contains the object, instead
// of the singleton_default class containing a static instance of the
// object, that object is guaranteed to be constructed (at the latest) in
// the first call to instance(). This permits calls to instance() from
// static code, even if that code is called before the file-scope objects
// in this file have been initialized.


Увы, но разрушение такого синглетона после всех глобальных объектов, которые им пользовались, не гарантируется.

Re[3]: [Trick] Упгрейд для синглтона
От: Quasi  
Дата: 29.08.07 15:14
Оценка: +1
Здравствуйте, remark, Вы писали:

R>Здравствуйте, eao197, Вы писали:


E>>Здравствуйте, remark, Вы писали:


R>>>Какие-нибудь мысли?


E>>А чем это лучше инициализации синглетонов на основе счетчиков Шварца?


R>На основе счетчиков Шварца тебе придётся делать некое подобие DCL.

R>Т.е. использовать InterlockedIncrement/InterlockedDecrement при каждом обращении.
R>Во-первых, это накладывает очень большое пенальти по скорости, особенно на многоядерных машинах (ну ты сам знаешь ).
R>Во-вторых, опять же проблемы с портированием. Как сделать это хорошо портируемым — вопрос (если ты, конечно, не используешь ACE ).

В данном подходе (счетчик Швардца) создается глобальный объект-инициализатор в каждой единице компиляции до использования синглтона. И предполагается как и в твоем случае, что глобальные объекты не запускают потоки при инициализации. Смотри, например, здесь. Поэтому, зачем там "InterlockedIncrement/InterlockedDecrement при каждом обращении"?

R>

Re[4]: [Trick] Упгрейд для синглтона
От: remark Россия http://www.1024cores.net/
Дата: 29.08.07 15:23
Оценка:
Здравствуйте, Quasi, Вы писали:

Q>В данном подходе (счетчик Швардца) создается глобальный объект-инициализатор в каждой единице компиляции до использования синглтона. И предполагается как и в твоем случае, что глобальные объекты не запускают потоки при инициализации. Смотри, например, здесь. Поэтому, зачем там "InterlockedIncrement/InterlockedDecrement при каждом обращении"?


Да, действительно. Недоглядел.
Ну тогда, примерно то же самое, только кода меньше писать.

R>>

Q>

1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: [Trick] Упгрейд для синглтона
От: Awaken Украина  
Дата: 29.08.07 15:40
Оценка:
R>static some_service& local = some_service(); // <-----------------
R>[/ccode]

R>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.


R>Какие-нибудь мысли?


это не работает, если твой синглтон находится в статической библиотеке ,
т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет.
в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости
Re[2]: Гибрид
От: Awaken Украина  
Дата: 29.08.07 15:44
Оценка:
R>+ создаётся по первому требованию
R>+ гарантированно создаётся "до main()"
R>- пока не отмечены

-не будет создан вообще, если он находится в статической либе
я с этим наигрался, и не придумал ничего более умного чем ручная инициализация.
т.е.
MyLib lib;
lib.Initialize(); // здесь создаются синглтоны
Re[2]: [Trick] Упгрейд для синглтона
От: remark Россия http://www.1024cores.net/
Дата: 29.08.07 15:51
Оценка:
Здравствуйте, Awaken, Вы писали:


R>>static some_service& local = some_service(); // <-----------------

R>>[/ccode]

R>>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.


R>>Какие-нибудь мысли?


A>это не работает, если твой синглтон находится в статической библиотеке ,

A>т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет.
A>в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости

Можно добавить видимость использования local


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: [Trick] Упгрейд для синглтона
От: remark Россия http://www.1024cores.net/
Дата: 29.08.07 16:04
Оценка: 1 (1)
Здравствуйте, remark, Вы писали:

R>Здравствуйте, Awaken, Вы писали:



R>>>static some_service& local = some_service(); // <-----------------

R>>>[/ccode]

R>>>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.


R>>>Какие-нибудь мысли?


A>>это не работает, если твой синглтон находится в статической библиотеке ,

A>>т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет.
A>>в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости

R>Можно добавить видимость использования local



vc8 не выбрасывает, если get_service() используется в проекте.

Если компилятор выбрасывает, то можешь сделать так:

static some_service& local = get_service();

static void f()
{
    local.make_something();
}

some_service& get_service()
{
    struct fake : some_service
    {
        fake() : m_f(&f) {}
        void (*m_f)();
    };
    static fake instance;
    return instance;
}



Так у него не будет шансов


R>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: [Trick] Упгрейд для синглтона
От: Awaken Украина  
Дата: 29.08.07 17:24
Оценка:
R>vc8 не выбрасывает, если get_service() используется в проекте.

vc++ 7.1 выбрасывал .
надо попробовать твой хак на других компиляторах, может прокатит

R>
R>static some_service& local = get_service();

R>Так у него не будет шансов

R>>

R>
Re[4]: [Trick] Упгрейд для синглтона
От: Sergey Россия  
Дата: 30.08.07 07:28
Оценка: 1 (1)
> R>>>static some_service& local = some_service(); // <-----------------
> R>>>[/ccode]
>
> R>>>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.
>
> R>>>Какие-нибудь мысли?
>
> A>>это не работает, если твой синглтон находится в статической библиотеке ,
> A>>т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет.
> A>>в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости
>
> R>Можно добавить видимость использования local
>
>
> vc8 не выбрасывает, если get_service() используется в проекте.
>
> Если компилятор выбрасывает, то можешь сделать так:
>
>
> static some_service& local = get_service();
> 
> static void f()
> {
>    local.make_something();
> }
> 
> some_service& get_service()
> {
>    struct fake : some_service
>    {
>        fake() : m_f(&f) {}
>        void (*m_f)();
>    };
>    static fake instance;
>    return instance;
> }
>

>
>
> Так у него не будет шансов
>
>
> R>
>

На VC от выбрасывания неплохо помогает __declspec(dllexport). Т.е.,
namespace {
__declspec(dllexport) void f()
{
   local.make_something();
}
}


Но при этом в случае либы хотя бы один символ из данного cpp файла должен быть использован где-то в проекте — что в данном случае автоматически выполняется. А вот со всякими саморегистрирующимися объектами беда ...
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[5]: [Trick] Упгрейд для синглтона
От: remark Россия http://www.1024cores.net/
Дата: 30.08.07 08:22
Оценка:
Здравствуйте, Sergey, Вы писали:

S>На VC от выбрасывания неплохо помогает __declspec(dllexport). Т.е.,


+1


S>Но при этом в случае либы хотя бы один символ из данного cpp файла должен быть использован где-то в проекте — что в данном случае автоматически выполняется. А вот со всякими саморегистрирующимися объектами беда ...


С саморегистрирующимися объектами патологическая беда, я так общего решения пока и не нашёл...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.