Как правильно использовать пулы памяти в стиле C ++ 11? - PullRequest
1 голос
/ 03 марта 2020

Я пытаюсь разработать внутреннюю механику простого встроенного приложения. Куски данных поступают в сеть, которые необходимо доставить компонентам, определяемым механизмом адресации. Несколько компонентов могут подписаться на один и тот же адрес. Я хочу разработать архитектуру, в которой входящие чанки инкапсулируются в объекты-оболочки, выделенные из пула памяти. Каждый компонент может удерживать оболочки (и данные внутри них) столько, сколько им нужно, и он должен быть освобожден, когда все компоненты пропустят go из него. В это время он возвращается в пул и снова готов к распределению. Исчерпание пула - не проблема.

Я планирую использовать эту реализацию пула памяти, которая удовлетворяет требованиям Allocator. Для автоматического c уничтожения объектов оболочки я планирую использовать std::shared_ptr, поэтому, когда все компоненты освобождают оболочку, она автоматически уничтожается и используемая память возвращается в пул.

Чего я не вижу Вот как эти две концепции могут объединиться. Если я выделю память из пула напрямую (вызывая allocate()), он даст мне указатель на блок данных, что нормально, но тогда как deallocate() будет вызываться автоматически? Или мне нужно использовать другой контейнер для моих объектов-оболочек, таких как std::list и передать ему распределитель пула памяти?

1 Ответ

0 голосов
/ 03 марта 2020

Вы можете использовать std::shared_ptr с пользовательским распределителем, используя std::allocate_shared. В любом случае, это, вероятно, то, что вам нужно, поскольку я предполагаю, что вы хотите, чтобы блок управления (т. Е. Счетчик ссылок) также выделялся с помощью распределителя пула.

При создании объекта с использованием std::allocate_shared, копия распределителя хранится внутри shared_ptr, поэтому при уничтожении будет вызываться правильный deallocate().

Обратите внимание, что вы также можете создать std::shared_ptr с помощью пользовательского средства удаления, например:

auto allocator = getAllocator<Foo>();
auto ptr = std::shared_ptr<Foo>(new(allocator.allocate()) Foo,
  [&allocator](auto * ptr) { allocator.deallocate(ptr); });

Однако, как я уже упоминал, это, вероятно, не то, что вам нужно, поскольку пространство для счетчиков ссылок не будет выделяться с использованием вашего объекта-распределителя.

Кстати, на случай, если вы все еще "ходите по магазинам" Вот еще одна реализация пула памяти, которая мне очень нравится: foonathan :: memory . Он предоставляет свои allocate_shared.

...