Мне было интересно о безопасности использования boost::fast_pool_allocator
с null_mutex
задавать.
Я знаю, что следующее является небезопасным экземпляром. Распределитель создается для каждого типа. Так что если у вас есть два контейнера, которые оба используют fast_pool_allocator<int, …null_mutex>
(скажем), они оба будут совместно использовать один и тот же экземпляр распределителя и, следовательно, приглашать гонки данных.
Большую озабоченность вызывает следующее. Интерфейс распределителя позволяет повторное связывание. Это означает, что даже если вы думаете, что используете fast_pool_allocator
с «локальным» типом, который вряд ли столкнется с другими экземплярами, контейнер может перепривязать этот распределитель к другому типу, такому как глобальный, который действительно конфликтует.
Вопрос в том, насколько безопасен boost::fast_pool_allocator
с null_mutex
?
Я считаю, что и pool_allocator, и fast_pool_allocator являются потокобезопасными,
от: http://www.boost.org/libs/pool/doc/html/header/boost/pool/pool_alloc_hpp.html
pool_allocator и pool_allocator будут оба
выделить / освободить из / в тот же пул.
Как будет fast_pool_allocator
Если до запуска main () и после него работает только один поток
main () заканчивается, тогда оба распределителя полностью поточно-ориентированы.
однако они не очень производительны по сравнению с другими способами уменьшения накладных расходов. Я также смотрел на tcmalloc от Google, который создает на кучу потоков, чтобы избежать блокировки.
Значением по умолчанию для этого параметра является boost :: details :: pool :: default_mutex
который является синонимом либо
boost :: details :: pool :: null_mutex (когда поддержка потоков
выключен в компиляторе (поэтому BOOST_HAS_THREADS не установлен), или
Поддержка потоков была явно отключена с помощью
BOOST_DISABLE_THREADS (широкополосное отключение потоков) или
BOOST_POOL_NO_MT (только для этой библиотеки)) или для boost :: mutex
(когда в компиляторе включена поддержка потоков).
boost::mutex
был установлен для меня, поэтому в моих тестах с резьбой у меня не было проблем — я думаю, это будет правильно для вас.
Но если нет, то у вас могут возникнуть проблемы, потому что:
Поскольку размер T используется для определения типа базового
Пул, каждый распределитель для разных типов одинакового размера будет делиться
тот же основной пул. Класс tag предотвращает пулы
делится между pool_allocator и fast_pool_allocator. Например, на
система, в которой sizeof (int) == sizeof (void *), pool_allocator и
pool_allocator будет выделять / освобождать из одного и того же
бассейн.
Других решений пока нет …