MemoryPool
C++ поток-безопасный пул памяти, легко сочетается с контейнерами C++ и пользовательскими классами. Подходит для сценариев с большим количеством объектов и повторным освобождением при построении объектов.
Запускаем четыре потока, каждый поток добавляет четыре вида объектов по пятьсот тысяч в свой std::list контейнер и освобождает их, каждый поток повторяет эту операцию десять раз (тестовый код находится в main.cpp).
Разделение модулей:
Распределение модулей в заголовочных файлах:
Особенность 1:
Особенность 2:
Особенность 3:
Принадлежность:
Принадлежность к потокам:
Пример использования:
int main(int argc, char* argv[])
{
//data используется только в основном потоке, поэтому использование AllocWkT (пул памяти, принадлежащий потоку) будет более эффективным
std::list<int, AllocWkT<int>> data{ 1, 2, 3, 4 };
for (auto& elem : data) ++elem;
return 0;
}
Объяснение: данные используются только в одном потоке, поэтому рекомендуется использовать пул памяти, принадлежащей этому потоку. Это обеспечивает более эффективное управление памятью.
Глобальная принадлежность:
Пример использования:
std::list<int, AllocWkG<int>> producer()
{
return std::list<int, AllocWkG<int>>{1, 2, 3, 4};
}
void consumer(std::list<int, AllocWkG<int>>& data)
{
for (auto& elem : data) ++elem;
}
int main(int argc, char* argv[])
{
//Получение данных в потоке производителя
auto future{std::async(std::launch::async, producer)};
auto data{ future.get() };
//Потребление в основном потоке
consumer(data);
//Данные пересекают основной поток и поток производителя, принадлежат глобальному пулу, поэтому используйте AllocWkG (глобальный пул) для обеспечения правильного освобождения памяти
return 0;
}
Объяснение: если данные используются несколькими потоками как общие данные, рекомендуется использовать глобальный пул памяти.
Общий вывод: если данные используются только в одном потоке, следует использовать пул памяти, принадлежащий этому потоку, а если данные являются общими для нескольких потоков, то следует использовать глобальный пул.
Полиморфизм:
class Human : public UseWkTP
{
std::string _name;
public:
virtual void work()
{
std::cout << "human work\n";
}
virtual ~Human(){}
};
class Teacher : public Human
{
int _id;
public:
void work() override
{
std::cout << "teacher work\n";
}
};
int main(int argc, char* argv[])
{
//Teacher объект использует указатель Human для удаления, используя полиморфные свойства, поэтому используется UseWkTP (пул памяти с полиморфными свойствами, принадлежащими потоку),
//используется ли поток или глобальная принадлежность, уже объяснено выше, использование полиморфных свойств гарантирует правильное освобождение пространства
//Если нет полиморфизма или не используется базовый класс для указания на производный класс, нет необходимости использовать полиморфный пул
Human* teacher{ new Teacher };
delete teacher;
return 0;
}
Вывод: если есть полиморфные классы или используется указатель базового класса для указания на производный класс, рекомендуется использовать полиморфный пул памяти. В остальных случаях это не требуется, что снижает накладные расходы.
#### Использование
* Компилятор поддерживает C++11 и выше.
* Подробные инструкции по использованию см. в main.cpp.
* Все примеры использования пулов памяти приведены на основе пула WukongMemoryPool. Другие пулы памяти могут быть заменены соответствующими сокращениями.
**Следующие пункты описывают использование пулов памяти:**
1. **Включение в тот же файл:**
* Для использования определенного пула памяти просто включите соответствующий файл заголовка пула, например, для использования пула WukongMemoryPool, #include «WukongMemoryPool.hpp».
* Если вы хотите использовать все пулы памяти, вы можете напрямую #include «MemoryPool.hpp».
2. **Создание пользовательских объектов с использованием пула:**
* Наследуйте от UseWk__ (публичное наследование).
* Пример:
```
#include "WukongMemoryPool.hpp"
using namespace hzw;
class A : public UseWk__ {...};//Использование пула WukongMemoryPool
A* a{new A};//Выделяем память из пула WukongMemoryPool
delete a;//Возвращаем память пулу WukongMemoryPool
```
3. **Использование контейнеров с пулом:**
* Используйте распределитель AllocWk__ для контейнера.
* Пример:
```
#include "WukongMemoryPool.hpp"
using namespace hzw;
std::list<int, AllocWk_<int>> list;//Использование пула WukongMemoryPool
```
4. **Прямое использование пула:**
* Пример:
```
#include "WukongMemoryPool.hpp"
using namespace hzw;
int main(int argc, char* argv[])
{
size_t bufSize{ 100 };
char* buf{ static_cast<char*>(WkG::allocate(bufSize)) };//Получаем память из пула WukongMemoryPool
WkG::deallocate(buf, bufSize);//Возвращаем память пулу WukongMemoryPool
return 0;
}
```
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )