Бывают сервисы (синглтоны), создание/разрушение которых контролируют вручную. Т.е. в коде инициализации/деинициализации приложения прописано что и в каком порядке создавать.
Бывают ленивые сервисы (синглтоны), которые создаются по первому требованию. Их традиционно сопутствует проблема защиты от многопоточного создания. На них либо можно вешать мьютексы (с некоторыми мьютексами возникает рекурсивная проблема их создания), либо использовать DCL, для элиминации цены на захват/освобождение мьютекса каждый раз.
Всё идеально, если такой синглтон гарантированно создавать в однопоточном окружении, тогда о синхронизации заботиться просто не надо. Но тут возникает одно НО. Надо гарантировать, что пользователь "дёрнет" этот синглтон в однопоточном окружении, т.е. во время создания глобальных объектов или в main() до запуска потоков. А если он этого не сделает, а будет его "дёргать" только из рабочих потоков?
Так вот, допустим есть такой h-ник с описанием сервиса:
Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.
Имхо, такая схема практически идеально подходит для создания низкоуровневых, ни-от-чего-не-зависящих глобальных сервисов. Например, сервис конвертации utf-8 <-> ucs-2, которому надо инициализировать таблицу конвертации символов, или сервис подсчёта crc, которому надо инициализировать таблицу кодов, или простенький сервис логирования, которому надо открыть файл. А так же, кстати, все сервисы, которым надо создать мьютекс, в однопоточном окружении это пока можно сделать безопасно, и использовать мьютекс уже в многопоточном окружении.
С этим трюком такие сервисы можно делать ещё немного более инкапсулированными и готовыми для повторного использования.
Здравствуйте, remark, Вы писали:
R>Какие-нибудь мысли?
Мысль только одна — порядок инициализации статических объектов в разных единицах трансляции не определен.
И эти статические объекты вполне себе могут нарожать потоков до запуска main.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, remark, Вы писали:
R>>Какие-нибудь мысли? J>Мысль только одна — порядок инициализации статических объектов в разных единицах трансляции не определен. J>И эти статические объекты вполне себе могут нарожать потоков до запуска main.
Патологические случаи запуска потоков, которые делают активную работу и обращаются к другим глобальным сервисам, из конструкторов глобальным объектов не рассматриваются
При желании сломать можно всё. Тут уж ничего не поделать. Сам себе злой буратино.
Ты ещё напомни про #define private public
Запуск же како-го пассивного потока, который только сам принимает обращения, такой синглтон прекрасно переживёт.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, remark, Вы писали:
R>>>Какие-нибудь мысли? J>>Мысль только одна — порядок инициализации статических объектов в разных единицах трансляции не определен. J>>И эти статические объекты вполне себе могут нарожать потоков до запуска main.
R>Патологические случаи запуска потоков, которые делают активную работу и обращаются к другим глобальным сервисам, из конструкторов глобальным объектов не рассматриваются
У меня таких злых буратин полвинчестера.
В мире проприетарного софта возможно все
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Какие-нибудь мысли?
E>А чем это лучше инициализации синглетонов на основе счетчиков Шварца?
На основе счетчиков Шварца тебе придётся делать некое подобие DCL.
Т.е. использовать InterlockedIncrement/InterlockedDecrement при каждом обращении.
Во-первых, это накладывает очень большое пенальти по скорости, особенно на многоядерных машинах (ну ты сам знаешь ).
Во-вторых, опять же проблемы с портированием. Как сделать это хорошо портируемым — вопрос (если ты, конечно, не используешь ACE ).
Здравствуйте, jazzer, Вы писали:
R>>Патологические случаи запуска потоков, которые делают активную работу и обращаются к другим глобальным сервисам, из конструкторов глобальным объектов не рассматриваются
J>У меня таких злых буратин полвинчестера. J>В мире проприетарного софта возможно все
Ну что ж, это не панацея.
Но по крайней мере и не ухудшение.
Здравствуйте, Ivan, Вы писали:
I>Здравствуйте, remark, Вы писали:
R>>Предлагаю назвать это Синглтон remark'а R>>Точно. Надо будет запостить на comp.lang.c++.moderated
I>если не ошибаюсь, это то же самое, что и http://www.rsdn.ru/Forum/Message.aspx?mid=1915245&only=1
Здравствуйте, remark, Вы писали:
R>... жаль только, что они не популяризируют свои идеи. Копаться в архивах boost mailing — это с ума сойти.
это решение все еще не идеальное — есть проблема управления порядком создания и разрушения нескольких синглтонов — в топике это как раз обсуждается, еще одна вариация на ту же тему http://www.rsdn.ru/Forum/Message.aspx?mid=1916208&only=1
Здравствуйте, remark, Вы писали: R>Например, сервис конвертации utf-8 <-> ucs-2, которому надо инициализировать таблицу конвертации символов,
Зачем преобразование UTF-8 <-> UTF-16 делать singleton-ом? По-моему, глобальная функция сойдёт. Даже если ускорять преобразование с помощью какой-нибудь таблицы, то она, скорее всего, известна во время компиляции, в run-time ничего делать не надо.
Здравствуйте, Пётр Седов, Вы писали:
ПС>Здравствуйте, remark, Вы писали: R>>Например, сервис конвертации utf-8 <-> ucs-2, которому надо инициализировать таблицу конвертации символов, ПС>Зачем преобразование UTF-8 <-> UTF-16 делать singleton-ом? По-моему, глобальная функция сойдёт. Даже если ускорять преобразование с помощью какой-нибудь таблицы, то она, скорее всего, известна во время компиляции, в run-time ничего делать не надо.
Это не суть данного поста.
Тут я ни в коем случае не хочу настаивать на том, как всем надо делать конвертацию utf-8 <-> ucs-2. Это приведено только для примера.
Тем не менее таблица конвертации там может быть, и заполняться она может в ран-тайм. Такой вариант тоже возможен.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, remark, Вы писали:
R>>... жаль только, что они не популяризируют свои идеи. Копаться в архивах boost mailing — это с ума сойти.
J>Они собираются специальный проект сделать под вытаскивание всяких таких вкусностей из потрохов буста. J>Как обычно, ни у кого нет времени
Вот это дело. Если начнут, то уже будет хорошо.
А то код там, конечно, хороший. Но подавляющее большинство его, так сказать, не представляет ничего нового и интересного. Поэтому просматривать весь код и мейлинг-листы достаточно скучно. А если смотреть бегло, то пропустишь самое интересное.
Здравствуйте, Ivan, Вы писали:
I>Здравствуйте, remark, Вы писали:
R>>... жаль только, что они не популяризируют свои идеи. Копаться в архивах boost mailing — это с ума сойти. I>это решение все еще не идеальное — есть проблема управления порядком создания и разрушения нескольких синглтонов — в топике это как раз обсуждается, еще одна вариация на ту же тему http://www.rsdn.ru/Forum/Message.aspx?mid=1916208&only=1
Что конкретно ты имеешь в виду?
Ленивость Синглтона Мейерса гарантирует создание до первого обращения.
С разрушением правда хуже. Но зачастую такие синглтоны можно и не рушить вообще. Если, речь идёт, например, об инициализации какой-то таблицы, или открытии файла.