NGINX内存池C代码移植项目

本文介绍了将nginx内存池的C代码按照面向对象的方式进行重构,简化了网络相关变量,并通过类的定义和成员方法实现内存管理。在C++中,使用const和using替代宏定义及typedef,将内存池操作封装为类的方法,实现了内存的申请和释放功能。通过测试验证了移植代码的正确性。
摘要由CSDN通过智能技术生成

nginx是一个高性能的HTTP和反向代理web服务器,是由伊戈尔·塞索耶夫为俄罗斯网站开发的,是一个开源的软件,底层由C语言编写完成,但经过提炼后,是可以将其按照面向对象的思想重新组织一下的,也相当于一个小项目吧。
涉及思路是将源文件中的几个主要函数实现成为类的成员方法,成员变量则只设置一个内存池对象即可。因为nginx内存池的结构比较复杂,涉及很多网络相关的东西,我们在本地编译器上对这些变量做了简化。

一、主要结构

源码中的一些结构体我们依旧使用结构体来实现,首先减免一些不必要的变量,防止在本地编译过程中增加不必要的麻烦。

//清理函数(回调函数)的类型
typedef void(*ngx_pool_cleanup_pt)(void *data);

struct ngx_pool_cleanup_s
{
   
	ngx_pool_cleanup_pt   handler;//定义了一个函数指针,保存清理操作的回调函数
	void                 *data;//传递给回调函数的参数
	ngx_pool_cleanup_s   *next;//所有的clean_up清理操作都被穿在链表上
};

//大块内存的头部信息
struct ngx_pool_large_s
{
   
	ngx_pool_large_s     *next;//大块内存串起来
	void                 *alloc;//保存分配出去的大块内存的起始地址
};

//分配小块内存的数据头
typedef struct ngx_pool_data_t 
{
   
	u_char               *last;//小块内存池可用内存的起始地址
	u_char               *end;//小块内存池可用内存的末尾地址
	ngx_pool_s           *next;//用于连接所有的小块内存
	ngx_uint_t            failed;//记录当前小块内存分配失败的次数
};

//内存池头部信息和管理成员信息
struct ngx_pool_s 
{
   
	ngx_pool_data_t       d;//存储头信息
	size_t                max;//小块内存和大块内存的分界
	ngx_pool_s           *current;//指向第一个可分配的内存块
	ngx_pool_large_s     *large;//指向大块内存的入口地址
	ngx_pool_cleanup_s   *cleanup;//清理占用的外部资源
};

二、全局变量的定义

因为在源码中使用了大量的宏定义来实现数值的替换,而在C++中我们则使用const关键字来替换源码中的宏,源码中使用了typedef关键字来进行类型重命名,在C++中我们使用C++11的using关键字来实现类型重定义,这是在代码上做的改变。

//类型重定义
using u_char = unsigned char;
using ngx_uint_t = unsigned int;

//把buff缓冲区清零
#define ngx_memzero(buf, n)       (void) memset(buf, 0, n)

//把数值d调整到临近的a的倍数
#define ngx_align(d, a)     (((d) + (a - 1)) & ~(a - 1))

//小块内存分配考虑字节对齐时的单位
#define NGX_ALIGNMENT   sizeof(unsigned long)

//把指针p调整到a的临近的倍数
#define ngx_align_ptr(p, a)                                                   \
    (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))

//默认物理页面的大小
const int ngx_pagesize = 4096;

//需要使用NGINX内存池分配的大小,超过则不统一管理
const int NGX_MAX_ALLOC_FROM_POOL = ngx_pagesize - 1;

//nginx内存池的默认大小
const int NGX_DEFAULT_POOL_SIZE = 16 * 1024;

//内存对齐的量
const int  NGX_POOL_ALIGNMENT = 16;

//ngx小块内存池最小的size调整成NGX_POOL_ALIGNMENT的临近的倍数
const int NGX_MIN_POOL_SIZE = 
			ngx_align((sizeof(ngx_pool_s) + 2 * sizeof(ngx_pool_large_s)),
				NGX_POOL_ALIGNMENT);

以上是一些标准量的定义,比如页面大小等等,在后续的实现中会陆续使用到。

三、类的定义

代码移植的整体思想是将内存池改为面向对象的思想,所以要对其方法以及变量进行封装,成员方法在类内只做声明,而在类外定义。

class ngx_mem_pool
{
   
public:
	//创建指定size大小的内存池,小块内存池不超过一个页面大小
	void* ngx_create_pool(size_t size);
	//考虑内存字节对齐,从内存池申请size大小的内存
	void *ngx_palloc(size_t size);
	//不考虑内存字节对齐
	void *ngx_pnalloc(size_t size);
	//调用pnalloc,并对内存块初始化为0
	void *ngx_pcalloc(size_t size);
	//释放大块内存
	void ngx_pfree(void *p);
	//内存池重置函数
	void ngx_reset_pool();
	//内存池销毁函数
	void ngx_destroy_pool();
	//添加回调的清理操作函数
	ngx_pool_cleanup_s *ngx_pool_cleanup_add(size_t size);

private:
	ngx_pool_s *pool;//指向nginx内存池的入口指针
	//小块内存分配
	void *ngx_palloc_small(size_t size,ngx_uint_t align);
	//分配新的小块内存池
	void *ngx_palloc_block(size_t size);
	//大块内存分配
	void 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值