Существует несколько интерфейсов, которые позволяют пользователям проявлять большую гибкость в том, как они хотят использовать Pools. Отзывы о концепциидокумент для получения базового понимания того, как работают различные пулы.
Использование объектов - это метод, при котором каждый пул является объектом, который может быть создан и уничтожен. Уничтожение бассейна косвенно освобождает все куски, которые были выделены из него.
Синглтон Использование — это метод, при котором каждый Бассейн является объектом со статической продолжительностью; то есть он не будет уничтожен до выхода программы. Бассейны с Singleton Использование может быть общим; таким образом, использование Singleton также подразумевает безопасность потока. Системная память, выделенная объектами пула с помощью Singleton Использование может быть освобождено с помощью release_memory или purge_memory.
Упорядоченный пул поддерживает свободный список в порядке адреса каждого свободного блока - это наиболее эффективный способ, если вы, вероятно, будете распределять массивы объектов. Тем не менее, освобождение объекта может быть O(N) в количестве свободных блоков, которые могут быть чрезмерно дорогими в некоторых ситуациях.
Неупорядоченный пул не поддерживает свой свободный список в каком-либо определенном порядке, в результате распределение и освобождение отдельных объектов очень быстро, но распределение массивов может быть медленным (и, в частности, пул может не знать, что он содержит достаточно свободной памяти для запроса распределения и излишне выделять больше памяти).
Интерфейс<pool
>является простым интерфейсом использования объектов с нулевым возвратом.
<pool
>является быстрым распределителем памяти и гарантирует правильное выравнивание всех выделенных кусков.
<pool.hpp
>Предоставляет дваКлассы UserAllocatorи a<template class pool
>, расширяющие и обобщающие рамки, предоставляемые решениемSimple Segregated Storage. Для получения информации о других интерфейсах на основе пула см. другиеИнтерфейсы пула.
Synopsis
Существует двакласса UserAllocator. В обоих случаях<pool.hpp
>.
Значение по умолчанию для параметра шаблонаUserAllocatorвсегда<default_user_allocator_new_delete
>.
struct default_user_allocator_new_delete
{
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static char * malloc(const size_type bytes)
{ return new (std::nothrow) char[bytes]; }
static void free(char * const block)
{ delete [] block; }
};
struct default_user_allocator_malloc_free
{
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static char * malloc(const size_type bytes)
{ return reinterpret_cast<char *>(std::malloc(bytes)); }
static void free(char * const block)
{ std::free(block); }
};
template <typename UserAllocator = default_user_allocator_new_delete>
class pool
{
private:
pool(const pool &);
void operator=(const pool &);
public:
typedef UserAllocator user_allocator;
typedef typename UserAllocator::size_type size_type;
typedef typename UserAllocator::difference_type difference_type;
explicit pool(size_type requested_size);
~pool();
bool release_memory();
bool purge_memory();
bool is_from(void * chunk) const;
size_type get_requested_size() const;
void * malloc();
void * ordered_malloc();
void * ordered_malloc(size_type n);
void free(void * chunk);
void ordered_free(void * chunk);
void free(void * chunks, size_type n);
void ordered_free(void * chunks, size_type n);
};
Example:
void func()
{
boost::pool<> p(sizeof(int));
for (int i = 0; i < 10000; ++i)
{
int * const t = p.malloc();
...
}
}
Интерфейс<template class object_pool
>- это интерфейс использования объектов с нулевым возвратом, но он знает тип объекта, для которого он выделяет куски. При разрушении любые куски, выделенные из этого<object_pool
>, будут иметь свои разрушители.
<object_pool.hpp
>обеспечивает тип шаблона, который может использоваться для быстрого и эффективного распределения памяти. Он также обеспечивает автоматическое уничтожение неразрушенных объектов.
Для получения информации о других интерфейсах на основе пула см. другиеИнтерфейсы пула.
Synopsis
template <typename ElementType, typename UserAllocator = default_user_allocator_new_delete>
class object_pool
{
private:
object_pool(const object_pool &);
void operator=(const object_pool &);
public:
typedef ElementType element_type;
typedef UserAllocator user_allocator;
typedef typename pool<UserAllocator>::size_type size_type;
typedef typename pool<UserAllocator>::difference_type difference_type;
object_pool();
~object_pool();
element_type * malloc();
void free(element_type * p);
bool is_from(element_type * p) const;
element_type * construct();
void destroy(element_type * p);
};
Template Parameters
ElementType
Параметр шаблона — это тип объекта для выделения/выделения. У него должен быть небросающий деструктор.
UserAllocator
Определяет метод, который базовый пул будет использовать для выделения памяти из системы. По умолчанию: default_user_allocator_new_delete. Смотрите __UserAllocatorдля деталей.
Пример:структура X {...}; // имеет деструктор с побочными эффектами.
void func()
{
boost::object_pool<X> p;
for (int i = 0; i < 10000; ++i)
{
X * const t = p.malloc();
...
}
}
singleton_pool.hpp
является интерфейсом Singleton Usage с Null Return. То же самое.
интерфейс бассейна, но с Singleton Usage вместо этого.
.
Synopsis
template <typename Tag, unsigned RequestedSize,
typename UserAllocator = default_user_allocator_new_delete>
struct singleton_pool
{
public:
typedef Tag tag;
typedef UserAllocator user_allocator;
typedef typename pool<UserAllocator>::size_type size_type;
typedef typename pool<UserAllocator>::difference_type difference_type;
static const unsigned requested_size = RequestedSize;
private:
static pool<size_type> p;
singleton_pool();
public:
static bool is_from(void * ptr);
static void * malloc();
static void * ordered_malloc();
static void * ordered_malloc(size_type n);
static void free(void * ptr);
static void ordered_free(void * ptr);
static void free(void * ptr, std::size_t n);
static void ordered_free(void * ptr, size_type n);
static bool release_memory();
static bool purge_memory();
};
Notes
Базовый пул<p
>, на который ссылаются статические функции в<singleton_pool
>, фактически объявляется таким образом, что он:
- Если же есть только одна нить, которая проходит до<
main()
>начала и после<main()
>окончания. Все статические функции singleton_pool синхронизируют их доступ к<p
>. - Гарантируется, что он будет построен до его использования, так что простой статический объект в приведенном выше синопсисе будет фактически неправильной реализацией. Реальная реализация, чтобы гарантировать это значительно сложнее.
Обратите вниманиена то, что для каждого набора параметров шаблона, включая параметры, специфичные для реализации, существует различный базовый пул<p
>.
Template Parameters
Tag
Параметр шаблонаTagпозволяет существовать различным неограниченным наборам одиночных пулов. Например, распределители пула используют два класса тегов, чтобы гарантировать, что два разных типа распределителей никогда не разделяют один и тот же базовый пул синглтонов.
Тагникогда не используется<singleton_pool
>.
Запрошенный размерЗапрошенный размер кусков памяти для выделения. Это передается в качестве параметра конструктора в базовый бассейн. Должно быть больше 0.
UserAllocator
Определяет метод, который базовый пул будет использовать для выделения памяти из системы. См. Распределители пользователей для деталей.
Пример:struct MyPoolTag {};
typedef boost::singleton_pool<MyPoolTag, sizeof(int)> my_pool;
void func()
{
for (int i = 0; i < 10000; ++i)
{
int * const t = my_pool::malloc();
...
}
my_pool::purge_memory();
}
<pool_allocator interface
>— интерфейс Singleton Usage с Исключениями. Он построен на интерфейсе singleton_pool и предоставляет класс Standard Allocator-compliant (для использования в контейнерах и т.д.).
Introduction
pool_alloc.hpp
Предоставляет два типа шаблонов, которые можно использовать для быстрого и эффективного распределения памяти. Эти типы удовлетворяют требованиям стандартного распределителя [20.1.5] и дополнительным требованиям [20.1.5/4], поэтому они могут использоваться со стандартными или поставляемыми пользователями контейнерами.
Для получения информации о других интерфейсах на основе пула см. другиеИнтерфейсы пула.
Synopsis
struct pool_allocator_tag { };
template <typename T,
typename UserAllocator = default_user_allocator_new_delete>
class pool_allocator
{
public:
typedef UserAllocator user_allocator;
typedef T value_type;
typedef value_type * pointer;
typedef const value_type * const_pointer;
typedef value_type & reference;
typedef const value_type & const_reference;
typedef typename pool<UserAllocator>::size_type size_type;
typedef typename pool<UserAllcoator>::difference_type difference_type;
template <typename U>
struct rebind
{ typedef pool_allocator<U, UserAllocator> other; };
public:
pool_allocator();
pool_allocator(const pool_allocator &);
template <typename U>
pool_allocator(const pool_allocator<U, UserAllocator> &);
pool_allocator & operator=(const pool_allocator &);
~pool_allocator();
static pointer address(reference r);
static const_pointer address(const_reference s);
static size_type max_size();
static void construct(pointer ptr, const value_type & t);
static void destroy(pointer ptr);
bool operator==(const pool_allocator &) const;
bool operator!=(const pool_allocator &) const;
static pointer allocate(size_type n);
static pointer allocate(size_type n, pointer);
static void deallocate(pointer ptr, size_type n);
};
struct fast_pool_allocator_tag { };
template <typename T
typename UserAllocator = default_user_allocator_new_delete>
class fast_pool_allocator
{
public:
typedef UserAllocator user_allocator;
typedef T value_type;
typedef value_type * pointer;
typedef const value_type * const_pointer;
typedef value_type & reference;
typedef const value_type & const_reference;
typedef typename pool<UserAllocator>::size_type size_type;
typedef typename pool<UserAllocator>::difference_type difference_type;
template <typename U>
struct rebind
{ typedef fast_pool_allocator<U, UserAllocator> other; };
public:
fast_pool_allocator();
fast_pool_allocator(const fast_pool_allocator &);
template <typename U>
fast_pool_allocator(const fast_pool_allocator<U, UserAllocator> &);
fast_pool_allocator & operator=(const fast_pool_allocator &);
~fast_pool_allocator();
static pointer address(reference r);
static const_pointer address(const_reference s);
static size_type max_size();
static void construct(pointer ptr, const value_type & t);
static void destroy(pointer ptr);
bool operator==(const fast_pool_allocator &) const;
bool operator!=(const fast_pool_allocator &) const;
static pointer allocate(size_type n);
static pointer allocate(size_type n, pointer);
static void deallocate(pointer ptr, size_type n);
static pointer allocate();
static void deallocate(pointer ptr);
};
Template Parameters
ТПервым параметром шаблона является тип объекта для выделения/выделения.
UserAllocatorОпределяет метод, который базовый пул будет использовать для выделения памяти из системы. См. Распределители пользователей для деталей.
Example:
void func()
{
std::vector<int, boost::pool_allocator<int> > v;
for (int i = 0; i < 10000; ++i)
v.push_back(13);
}