Для любого заданного<T>, тип<flyweight<T>>поддерживает некоторые общие или статические данные, которые должны быть должным образом инициализированы, прежде чем класс может быть использован. Внутренний механизм роста. Flyweight гарантирует, что статическая инициализация данных происходит автоматически перед первым использованием конкретной<flyweight<T>>инстанциации в программе, и в любом случае всегда во время так называемойфазы динамической инициализациипоследовательности запуска программы. Хотя стандарт C++ не требует этого строго, в текущей практике динамическая инициализация завершается до начала<main()>.
Таким образом, для всех практических целей инициализация статических данных выполняется до<main()>или до первого предварительного<main()>использования класса, например, если мы объявляем глобальный<static flyweight<T>>объект. Это охватывает подавляющее большинство случаев использования прозрачным образом, но есть некоторые сценарии, где политика автоматической статической инициализации данных Boost. Вес может потерпеть неудачу:
// global thread poolclassthread_pool{public:thread_pool(){for(inti=0;i<100;++i)p[i]=shared_ptr<thread>(newthread(thread_fun));}private:staticvoidthread_fun(){// uses flyweight<std::string>}array<shared_ptr<thread>,100>p;};staticthread_poolthpool;intmain(){...
Глобальный пул примеров запускает несколько потоков, каждый из которых внутренне использует<flyweight<std::string>>. Статическая инициализация данных потенциально может выполняться дважды одновременно, если два потока сталкиваются при первом использовании<flyweight<std::string>>: Повышаю. Весовая инициализация не учитывает безопасность резьбы. Таким образом, мы должны явно позаботиться о инициализации статических данных в безопасном контексте потока перед запуском потоков:
Функция статического элемента<init>также небезопасна: в нашем конкретном примере она просто называется в одной резьбовой среде. Когда может произойти параллелизм,<flyweight<T>::init>должен быть правильно синхронизирован программистом, используя некоторые собственные механизмы взаимного исключения.
Ниже приведен еще один пример, когда по умолчанию статическая инициализация предоставлена Boost. Вес может потерпеть неудачу:
staticstd::vector<flyweight<std::string>>v;intmain(){// use v}
В некоторых средах программа выше не срабатывает при выходе. Например, при запуске из среды Microsoft Visual C++ в режиме отладки запускается точка останова во время завершения и окно вывода отладки показывает сообщение вдоль следующего:
HEAP[test.exe]: HEAP: Free Heap block 3a6488 modified at 3a6650 after it was
freed
Windows has triggered a breakpoint in test.exe.
This may be due to a corruption of the heap, and indicates a bug in test.exe
or any of the DLLs it has loaded.
The output window may have more diagnostic information
В чем проблема? Хотя тип<v>включает<flyweight<std::string>>, построение<v>в качестве пустого вектора не обязательно должно создавать какой-либо объект с массой мухи; поэтому вполне возможно, что статическая инициализация<flyweight<std::string>>происходитпослестроительства<v>; когда это происходит, статическое разрушение связанной фабрики произойдетдо<v>разрушения, оставляя вектор с болтающимися весами мухи. Опять же, решение состоит в явном принуждении статического инстанциирования<flyweight<std::string>>до создания<v>. Здесь вызов функции<flyweight<std::string>::init>немного громоздкий, поэтому мы можем прибегнуть к типу полезности<flyweight<std::string>::initializer>, чтобы сделать эту работу для нас:
// equivalent to calling flyweight<std::string>::init()staticflyweight<std::string>::initializerfwinit;staticstd::vector<flyweight<std::string>>v;intmain(){// use v; no dangling flyweights at termination now}
Статья Boost.Flyweight Documentation - Tutorial - Technical issues раздела Boost.Flyweight Documentation - Tutorial может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.