boost的pool内存池

参考《boost程序库开发完全指南》

//pool_func_eg.h

#pragma once
#include<iostream>
#include<boost\pool\pool.hpp>

using namespace boost;
void eg();
void eg_object_pool();
void eg_construct();
void eg_singleton_pool();
//object_pool.coo

#include"pool_func_eg.h"
/*
	object_pool的特殊之处是construct和destroy函数,这两个函数是object_pool的真正价值所在。
	construct先调用malloc分配内存,然后再在内存块上使用传入的参数调用类的构造函数,返回的是一个已经初始化的对象指针(类似于make_shared)
	destroy则先调用对象的析构函数,然后再用free释放内存块
*/
#include<boost\pool\object_pool.hpp>
struct demo_class {            //一个示范用的类
public:
	int a, b, c;
	demo_class(int x=1,int y=2,int z=3):a(x),b(y),c(z){}
};
void eg_object_pool() {
	object_pool<demo_class> p1;                   //对象内存池

	demo_class * dc = p1.malloc();                //分配一个原始内存块
	assert(p1.is_from(dc));

	//dc指向的内存未经初始化
	assert(dc->a != 1 || dc->b != 2 || dc->c != 3);

	dc = p1.construct(2, 3, 4);
	assert(dc->a == 2);

	object_pool<std::string> p2;
	for (int i = 0; i < 10 ; ++i) {                //连续分配大量的string
		std::string *ps = p2.construct("hello");
		std::cout << *ps << std::endl;
	}
}                                           //所有对象都在这里被析构释放
/*
	使用更多的构造参数:
	construct默认最多只能使用3个参数创建对象,但constructor被设计为可扩展的
	pool库在目录boost/pool/detail下提供了一个名为pool_construct.m4和pool_construct_simple.m4的脚本
	并同时提供可在Unix/Linux和Windows下运行的同名sh和bat可执行脚本文件,只要简单的向批处理脚本传递一个整数参数N,
	m4就能自动生成具有N个参数的construct源码
*/
/*
	自定义扩展construct,若临时的想要扩展参数的数量,可以自定义一个construct函数
	下面代码模仿construct函数实现了一个可接受4个参数的创建函数
*/
struct demo_class1 {            //一个示范用的类
public:
	int a, b, c,d;
	demo_class1(int x = 1, int y = 2, int z = 3,int u =  4) :a(x), b(y), c(z),d(u) {}
};
template<typename P,typename T0,typename T1,typename T2,typename T3>
inline typename P::element_type * construct(P &p, const T0 & a0, const T1 & a1, const T2& a2, const T3& a3) {
	typename P::element_type * mem = p.malloc();
	assert(mem != 0);
	new(mem)P::element_type(a0, a1, a2, a3);             //定位new运算符
	return mem;
}
void eg_construct() {
	object_pool<demo_class1> op1;
	demo_class1 * dc1 = construct(op1, 2, 3, 4, 5);
	std::cout << dc1->a << " " << dc1->b << std::endl;
}
//singleton_pool.cpp

#include"pool_func_eg.h"
/*
	singleton_pool与pool的接口完全一致,可以分配简单数据类型的内存指针,但它是一个单件,并提供线程安全
*/
#include<boost/pool/singleton_pool.hpp>
/*
	singleton_pool的成员函数均是静态的,因此不会产生single_ton的实例,调用函数的时候直接用域操作符
	所以它的生命周期与整个程序一样长,除非手动调用release_memory或purge_memory,否则singleton_pool不会自动释放占用的内存
*/
struct pool_tag{};             //空类,仅仅用于标记
typedef singleton_pool<struct pool_tag, sizeof(int)> sp;   //内存池定义
void eg_singleton_pool() { 
	int *p = (int *)sp::malloc();   //分配内存块
	assert(sp::is_from(p));
	sp::release_memory();
}

//Mainpool.cpp

//用来测试各个cpp中的函数

/*
	pool库基于简单的分隔存储思想实现了一个简单的内存池库,不仅能够管理大量的对象,还可以用作STL的内存分配器
	pool库包含4个部分:最简单的pool,分配类实例的object_pool,单件内存池singleton_pool,可用于标准库的pool_alloc
*/
#include"pool_func_eg.h"

/*
	pool的模板类型参数UserAllocator是一个用户定义的内存分配器,它实现了特定的内存分配算法,通常
	可以直接用默认的default_user_allocator_new_delete
	pool的构造函数接受一个size_type类型的整数request_size只是每次pool分配内存块的大小(不是内存池的大小)
	在析构时,pool将自动释放内存
	成员函数malloc和ordered_malloc的行为更类似于C中的全局函数malloc,void*指针返回从内存池中分配的内存块
	大小为构造函数中指定的requested_size如果分配失败,函数返回0,不会抛出异常
	malloc从内存池中任意分配一个内存块,order_malloc则在分配的同时合并空闲块链表。
	order_malloc带参数的形式还可以连续分配n快的内存,分配后的内存块可以用is_from函数测试是否是从这个内存池分配出去的
	与malloc对应的函数是free,用来手工释放之前分配的内存块,这些内存块必须是从这个内存池分配出去的
	一般情况下内存池会自动管理内存分配,不应该调用free函数,除非你认为内存池的空间已经不足,必须释放已经分配的内存
	还有两个成员函数release_memory让内存池释放所有未被分配的内存,已分配的内存不受影响
	purge_memory则强制释放内存池持有的所有内存,这两个函数一般情况下也不应该手工调用
*/

//example for pool
//pool只能用于int double 等类型的内存池
void eg_pool() {
	pool<> p(sizeof(int));               //一个可分配int的内存池

	int *p1 = (int *)p.malloc();         //必须把void*类型转换为需要的类型
	assert(p.is_from(p1));

	p.free(p1);                          //释放内存池分配的内存块


	for (int i = 0; i < 100; ++i) {      //连续分配大量内存
		p.ordered_malloc(10);            //pool在分配内存的时候不会抛出异常,所以实际编写的代码应该检查返回的指针是否为空
	}                              
}                                        //内存池对象析构,所有分配的内存在这里都被释放
int main() {
	eg_object_pool();
	eg_construct();
	eg_singleton_pool();
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值