Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2321003
  • 博文数量: 252
  • 博客积分: 5472
  • 博客等级: 大校
  • 技术积分: 3107
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-17 18:39
文章分类

全部博文(252)

文章存档

2012年(96)

2011年(156)

分类: LINUX

2012-03-15 14:43:58

ngx_array

对应的文件为 core/ngx_array.{c|h}

ngx_array是nginx内部封装的使用 ngx_pool_t对内存池进行分配的数组容器,其中的数据是在一整片内存区中连续存放的。更新数组时只能在尾部压入1个或多个元素。

数组的实现结构为

  1. struct ngx_array_s {
  2. void *elts;
  3. ngx_uint_t nelts;
  4. size_t size;
  5. ngx_uint_t nalloc;
  6. ngx_pool_t *pool;
  7. };

其中 elts 为具体的数据区域的指针, nelts 为数组实际包含的元素数量, size为数组单个元素的大小, nalloc为数组容器预先(或者重新)分配的内存大小, pool 为分配基于的内存池

常用的操作有


  1. // 创建一个新的数组容器
  2. ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);

  3. // 销毁数组容器
  4. void ngx_array_destroy(ngx_array_t *a);

  5. // 将新的元素加入数组容器
  6. void *ngx_array_push(ngx_array_t *a);
  7. void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n); //返回n个元素的指针

这里需要注意的是,和之前的ngx_pool_cleanup_add一样, ngx_array_push只是进行内存分配的操作,我们需要对返回的指针指向的地址进行赋值等操作来实现实际数组值的添加。

具体一点的push操作的实现为,

  1. 首先判断 nalloc是否和nelts相等,即数组预先分配的空间已经满了,如果没满则计算地址直接返回指针
  2. 如果已经满了则先判断是否我们的pool中的当前链表节点还有剩余的空间,如果有则直接在当前的pool链表节点中分配内存,并返回
  3. 如果当前链表节点没有足够的空间则使用ngx_palloc重新分配一个2倍于之前数组空间大小的数组,然后将数据转移过来,并返回新地址的指针

下面是一个array的例子:

demo/basic_types/array_and_hash.c

  1. #include <stdio.h>
  2. #include "ngx_config.h"
  3. #include "ngx_conf_file.h"
  4. #include "nginx.h"
  5. #include "ngx_core.h"
  6. #include "ngx_string.h"
  7. #include "ngx_palloc.h"
  8. #include "ngx_array.h"

  9. volatile ngx_cycle_t *ngx_cycle;

  10. void
  11. ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
  12.             const char *fmt, ...)
  13. {
  14. }

  15. int main()
  16. {
  17.    ngx_pool_t* pool;
  18.    ngx_array_t* arr;
  19.    int n;
  20.    int* ele;
  21.    pool = ngx_create_pool(4000, NULL);
  22.    arr = ngx_array_create(pool, 10, sizeof(ngx_uint_t));
  23.    for (n=0; n < 5; n++) {
  24.       ele = (int*) ngx_array_push(arr);
  25.       *ele = n;
  26.       printf("new element %d added\n", n);
  27.    }

  28.    printf("arr->nelts is %d, arr->nalloc = %d\n", arr->nelts, arr->nalloc);

  29.    for (n=5; n < 15; n++) {
  30.       ele = (int*) ngx_array_push(arr);
  31.       *ele = n;
  32.       printf("new element %d added\n", n);
  33.    }
  34.    printf("arr->nelts is %d, arr->nalloc = %d\n", arr->nelts, arr->nalloc);

  35.    ngx_array_destroy(arr);
  36.    ngx_destroy_pool(pool);
  37.    return 0;
  38. }
编译运行
  1. gcc -c -O -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Wunused-function -Wunused-variable -Wunused-value -Werror -g -I ../../../objs/ -I ../../os/unix array_and_hash.c -I../../core/ -I../../event/ -I../../os/ -o array_and_hash.o
  2. gcc -o array_and_hash array_and_hash.o ../../../objs/src/core/ngx_{string,palloc,array}.o ../../../objs/src/os/unix/ngx_alloc.o -lcrypt -lpcre -lcrypto -lz


  3. ./array_and_hash
输出
  1. new element 0 added
  2. new element 1 added
  3. new element 2 added
  4. new element 3 added
  5. new element 4 added
  6. arr->nelts is 5, arr->nalloc = 10
  7. new element 5 added
  8. new element 6 added
  9. new element 7 added
  10. new element 8 added
  11. new element 9 added
  12. new element 10 added
  13. new element 11 added
  14. new element 12 added
  15. new element 13 added
  16. new element 14 added
  17. arr->nelts is 15, arr->nalloc = 15


阅读(1633) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~