.. role:: blue :class: blue Реализация многопоточных кэшей ============================== .. _Multithreaded_caches_implementation: .. версия ядра: Базовый класс для кэшированных данных и класс менеджера кэшей определены в файле *tool_multithreading.h*. Менеджер кэшей CacheManager --------------------------- Менеджер кэшей определен как шаблонный класс **CacheManager** для класса кэшированных данных и содержит члены: - **longTerm** – данные главного потока; используются при последовательном выполнении и для инициализации данных потоков при параллельном выполнении. - **tcache** – список кэшей с данными, которые используются при параллельном выполнении. Каждый поток по идентификатору threadKey использует только свою копию данных. Для многопоточной обработки зависимых (имеющих общие данные) объектов должен использоваться режим многопоточных вычислений :ref:`mtm_Items `. - **lock** – блокировка менеджера кэшей, которая используется при изменении списка кэшей и изменении кэша главного потока. Шаблонный класс **CacheManager\** реализует методы: - **T \* operator()** – возвращает указатель на кэш (данные) текущего потока. Всегда возвращает ненулевое значение. - **void Reset( bool resetLongTerm )** – аннулирует данные кэшей. Если resetLongTerm == true, также удаляет кэш главного потока. - **void CleanAll( bool doPostproc, bool force )** – удаляет все кэши и отписывается от сборки мусора. Должна вызываться в последовательном участке кода. - **T \* LongTerm()** – возвращает указатель на кэш (данные) главного потока. Всегда возвращает ненулевое значение. Все операции с кэшем главного потока должны быть защищены блокировкой кэша. - :blue:`CommonMutex` **\* GetLock()** – возвращает указатель на блокировку для операций с кэшем главного потока с учетом того, исполняется ли код параллельно. Может возвращать нулевое значение (удобно для использования с :blue:`ScopedLock`). - :blue:`CommonMutex` **\* GetLockHard()** – возвращает указатель на блокировку для операций с кэшем главного потока. Всегда возвращает ненулевое значение. - **bool ResetCacheData()** – функция очистки, используемая сборщиком мусора. Алгоритм работы менеджера кэшей зависит от режима многопоточности ядра :blue:`MbeMultithreadedMode`. Если определен режим многопоточных вычислений не ниже :blue:`mtm_SafeItems`, менеджер кэшей инициирует использование выделенных кэшей для каждого потока. При этом менеджер кэшей по идентификатору потока выбирает и выдает потоку его копию данных. При переходе к последовательной работе менеджер вызывает функцию **Postprocess()** для пост-обработки кэшей. Указанная функция итерируется по кэшам, использованным при параллельных вычислениях, и вызывает функцию :blue:`longTerm.MergeWith`\( AuxiliaryData \* ) с данными каждого кэша в качестве параметра. После завершения работы функции **Postprocess()** многопоточные кэши удаляются. Далее на запрос кэша менеджер кэшей выдает только кэш главного потока (**longTerm**). Класс :blue:`CacheManager` является производным от класса :blue:`CacheCleaner`, что позволяет запускать чистку кэшей по требованию. Базовый класс кэшированных данных AuxiliaryData ----------------------------------------------- Класс кэшированных данных должен наследоваться от базового класса **AuxiliaryData** и содержать определения конструктора по умолчанию и конструктора копирования. Кроме того, если требуется пост-обработка кэшей после выхода из параллельных вычислений, наследник класса :blue:`AuxiliaryData` должен переопределить метод **void MergeWith( AuxiliaryData \* )**, который вызывается менеджером кэшей для данных основного потока с данными каждого из многопоточных кэшей в качестве параметра. Реализация **MergeWith()** по умолчанию не делает никакой пост-обработки. Класс объекта ядра, использующего кэширование, должен определять кэшированные данные как класс, наследованный от :blue:`AuxiliaryData`, и включать в себя экземпляр :blue:`CacheManager` как член класса. При многопоточной обработке зависимых (имеющих общие данные) объектов должен использоваться режим многопоточных вычислений не ниже :blue:`mtm_SafeItems`.