转载申明:本文可以任意转载,但需注明原文地址,谢谢!
俄罗斯大牛在nginx中给我们封装了非常好用的数组,在做nginx模块开发的时候,不必再使用原始的数组了。
nginx使用以下结构来维护数组
struct ngx_array_s { void *elts; ngx_uint_t nelts; size_t size; ngx_uint_t nalloc; ngx_pool_t *pool; };
通过对数组结构成员的了解,可以得之:elts所指的内存大小 = size * nalloc。
nginx给我们提供了5个接口函数,方便进行数组的操作,分别是:
ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
此函数即是用来创建一个可以存储n个元素,每个元素大小为size的数组。返回值是维护数组的结构的地址。
void ngx_array_destroy(ngx_array_t *a)
此函数顾名思义就是释放内存、销毁数组,但nginx并没有真正的释放内存,而是将内存归还给内存池(a->pool)。
void *ngx_array_push(ngx_array_t *a);
此函数的功能就是取得下一个可以存放元素的单元地址。由于nginx封装的数组可以根据需求动态扩展,所以此函数必须处理预分配的内存不足的情况。nginx在ngx_array_push函数内存采用了两种策略来动态增加内存。
此接口函数是nginx模块开发中,使用最多的数组操作接口了,列举一个简单的使用例子:
typedef struct { int age; char *name; } person_t; person_t *p = ngx_array_push(a); /*a 是一个被创建的用来存放person_t类型元素的数组*/ p->age = 23; p->name = (char *)"marcky";
nginx数组的用法就是先申请内存,然后再向内存中填充数据;这是俄罗斯大牛在整个nginx中的编码手法。
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
从函数名也可以猜到它是用来获得n个元素的内存空间地址,然后从获得的地址向数组中填入n个元素。好像使用得比较少。此操作面临数组空间不足的时候,也是采用了类似ngx_array_push的两个动态增加内存的策略。但存在略微的不同之处。读源码可以了解到。
static ngx_inline ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
此接口函数用来为我们初始化一个定义的数组。用法举例:
ngx_array_t a; /*定义数组a,但数组a只是一个维护数组的结构,还没有真正存放元素的内存空间,所以得初始化它。*/ ngx_array_init(&a, p, 10, sizeof(int) ); /*将数组初始化为可以存放10个整型元素的数组*/
到此,nginx所封装的数组也就学习完了,鼓励自己继续努力研究nginx。