nginx 学习笔记(三)基本数据结构
2017-06-14 22:38
225 查看
在开发nginx模块之前,要先了解nginx的一些基本的数据结构。。
类似的还有ngx_uint_t是uintptr_t的一个typedef
其中len是字符串的长度,data指向字符串的地址,这样的话如果有多个同样的字符串,就可以让data指向同一个地址,节省空间。data不保证字符串后会添加\0,所以在使用ngx_str_t的data成员时候,不要使用strcpy等这些以\0标识结尾的函数。
用来简化ngx_str_t使用的宏有:
ngx_string(text) - 初始化ngx_str_t时使用
ngx_null_string - 相当于ngx_string(“”)
ngx_str_set(str, text) - 设置一个已有的str为text的内容
ngx_str_null(str) - 设置一个已有的str为空字符串
其中成员的含义如下:
elts:元素
nelts: 当前元素的个数
size:每个元素的大小
nalloc:元素的上限个数
pool:内存池,也就是说需要的内存都是从pool获取的
以及相关函数
ngx_buf_t代表的是缓冲区,其中各个成员含义如下:
pos:缓冲区的起始位置
last:缓冲区的终止位置
file_pos:缓冲文件时,file_pos代表文件的起始位置
file_last:缓冲文件时,file_last代表文件的结束位置
start:整个缓冲区的开始位置
end:整个缓冲区的结束位置
tag:实际上是一个void*类型的指针,使用者可以关联任意的对象上去,只要对使用者有意义。
file:处理文件时,代表文件对象
shadow:当某一个buf和另一个buf要处理同一个文件或者同一块缓冲区的时候,就不再拷贝一份过来,而是直接指向同一块内存,并且两个buf的shadow指向对方,所以此时释放内存的时候容易造成多次释放,要特别小心
temporary:1:为1代表是用户建立的临时内存块,并且内容可以修改
memory:1:为1代表数据在内存中,但是不能被修改
mmap:1:为1代表数据是放在使用mmap()这个系统调用映射过来的内存中,并且不可以被修改
recycled:1:可以被回收的,也就是可以被释放的
in_file:1:为1代表处理的是文件
flush:1:遇到有flush字段被设置为1的的buf的chain,则该chain的数据即便不是最后结束的数据(last_buf被设置,标志所有要输出的内容都完了),也会进行输出,不会受postpone_output配置的限制,但是会受到发送速率等其他条件的限制。
sync:1:这块内存是否用同步操作进行(可能会阻塞nginx)
last_buf:1:当这个buf在多个ngx_chain_t内,标识着是否是最后一块buf
last_in_chain:1:是否是当前这个ngx_chain_t的最后一块buf,所以last_buf一定是last_in_chain,但是last_in_chain不一定是last_buf,因为可能在另一个chain里这个buf不是那个chain的最后一个buf
last_shadow:1:当多个buf互相是shadow的时候,是否是最后一个shadow,在创建一个buf的shadow的时候,通常将新创建的一个buf的last_shadow置为1。
temp_file:1:当内存不够的时候,buf的内容需要写到临时文件内,由这个标识位来标识
nginx定义了两个宏来方便的创建buf
也可以使用定义好的函数来创建一个临时的内存块,size为内存的大小
容易看出实际上ngx_chain_t就是ngx_buf_t的一个链表而已。。
可以使用ngx_alloc_chain_link()来创建一个chain,原型如下
可以使用ngx_free_chain(pool, cl)宏来释放一个chain的节点
容易看出,释放一个chain的节点实际上只是把这个节点放到pool的chain成员上去了,实际上节点并没有被真正的释放,这样的话下次再申请节点的时候可以直接从chain这个成员上拿下来。
ngx_int_t
实际上ngx_int_t就是intptr_t的一个typedef类似的还有ngx_uint_t是uintptr_t的一个typedef
ngx_str_t
ngx_str_t在模块开发时经常用到,代表的就是一个字符串,定义如下:typedef struct { size_t len; u_char *data; } ngx_str_t;
其中len是字符串的长度,data指向字符串的地址,这样的话如果有多个同样的字符串,就可以让data指向同一个地址,节省空间。data不保证字符串后会添加\0,所以在使用ngx_str_t的data成员时候,不要使用strcpy等这些以\0标识结尾的函数。
用来简化ngx_str_t使用的宏有:
ngx_string(text) - 初始化ngx_str_t时使用
ngx_null_string - 相当于ngx_string(“”)
ngx_str_set(str, text) - 设置一个已有的str为text的内容
ngx_str_null(str) - 设置一个已有的str为空字符串
ngx_array_t
定义如下typedef struct ngx_array_s ngx_array_t; struct ngx_array_s { void *elts; ngx_uint_t nelts; size_t size; ngx_uint_t nalloc; ngx_pool_t *pool; };
其中成员的含义如下:
elts:元素
nelts: 当前元素的个数
size:每个元素的大小
nalloc:元素的上限个数
pool:内存池,也就是说需要的内存都是从pool获取的
以及相关函数
/* 在内存池p上分配n个元素,每个元素大小为size,返回构造好的ngx_array_t的地址 */ ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size); /* 销毁一个ngx_array_t,会由内存池自动释放内存 */ void ngx_array_destroy(ngx_array_t *a); /* 在ngx_array_t上添加一个元素,返回元素的地址 */ void *ngx_array_push(ngx_array_t *a); /* 在ngx_array_t上添加n个元素,返回元素的地址 */ void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n); /* *初始化一个已经存在的ngx_array_t *例如 ngx_array_t b; *ngx_array_init(&b, pool, 5, sizeof(int)); */ 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_buf_t
定义:struct ngx_buf_s { u_char *pos; u_char *last; off_t file_pos; off_t file_last; u_char *start; /* start of buffer */ u_char *end; /* end of buffer */ ngx_buf_tag_t tag; ngx_file_t *file; ngx_buf_t *shadow; /* the buf's content could be changed */ unsigned temporary:1; /* * the buf's content is in a memory cache or in a read only memory * and must not be changed */ unsigned memory:1; /* the buf's content is mmap()ed and must not be changed */ unsigned mmap:1; unsigned recycled:1; unsigned in_file:1; unsigned flush:1; unsigned sync:1; unsigned last_buf:1; unsigned last_in_chain:1; unsigned last_shadow:1; unsigned temp_file:1; /* STUB */ int num; };
ngx_buf_t代表的是缓冲区,其中各个成员含义如下:
pos:缓冲区的起始位置
last:缓冲区的终止位置
file_pos:缓冲文件时,file_pos代表文件的起始位置
file_last:缓冲文件时,file_last代表文件的结束位置
start:整个缓冲区的开始位置
end:整个缓冲区的结束位置
tag:实际上是一个void*类型的指针,使用者可以关联任意的对象上去,只要对使用者有意义。
file:处理文件时,代表文件对象
shadow:当某一个buf和另一个buf要处理同一个文件或者同一块缓冲区的时候,就不再拷贝一份过来,而是直接指向同一块内存,并且两个buf的shadow指向对方,所以此时释放内存的时候容易造成多次释放,要特别小心
temporary:1:为1代表是用户建立的临时内存块,并且内容可以修改
memory:1:为1代表数据在内存中,但是不能被修改
mmap:1:为1代表数据是放在使用mmap()这个系统调用映射过来的内存中,并且不可以被修改
recycled:1:可以被回收的,也就是可以被释放的
in_file:1:为1代表处理的是文件
flush:1:遇到有flush字段被设置为1的的buf的chain,则该chain的数据即便不是最后结束的数据(last_buf被设置,标志所有要输出的内容都完了),也会进行输出,不会受postpone_output配置的限制,但是会受到发送速率等其他条件的限制。
sync:1:这块内存是否用同步操作进行(可能会阻塞nginx)
last_buf:1:当这个buf在多个ngx_chain_t内,标识着是否是最后一块buf
last_in_chain:1:是否是当前这个ngx_chain_t的最后一块buf,所以last_buf一定是last_in_chain,但是last_in_chain不一定是last_buf,因为可能在另一个chain里这个buf不是那个chain的最后一个buf
last_shadow:1:当多个buf互相是shadow的时候,是否是最后一个shadow,在创建一个buf的shadow的时候,通常将新创建的一个buf的last_shadow置为1。
temp_file:1:当内存不够的时候,buf的内容需要写到临时文件内,由这个标识位来标识
nginx定义了两个宏来方便的创建buf
#define ngx_alloc_buf(pool) ngx_palloc(pool, sizeof(ngx_buf_t)) #define ngx_calloc_buf(pool) ngx_pcalloc(pool, sizeof(ngx_buf_t))
也可以使用定义好的函数来创建一个临时的内存块,size为内存的大小
ngx_int_t ngx_create_temp_buf(ngx_pool_t *pool, size_t size)
ngx_chain_t
定义如下:typedef struct ngx_chain_s 4000 ngx_chain_t; struct ngx_chain_s { ngx_buf_t *buf; ngx_chain_t *next; };
容易看出实际上ngx_chain_t就是ngx_buf_t的一个链表而已。。
可以使用ngx_alloc_chain_link()来创建一个chain,原型如下
ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool);
可以使用ngx_free_chain(pool, cl)宏来释放一个chain的节点
#define ngx_free_chain(pool, cl) \ cl->next = pool->chain; \ pool->chain = cl
容易看出,释放一个chain的节点实际上只是把这个节点放到pool的chain成员上去了,实际上节点并没有被真正的释放,这样的话下次再申请节点的时候可以直接从chain这个成员上拿下来。
相关文章推荐
- nginx 源码学习笔记(六)——nginx基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 源码学习笔记(六)——nginx基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 学习笔记(三)基本数据结构
- nginx 源码学习笔记(六)——nginx基本数据结构
- 数据结构学习笔记:基本知识