nginx中基础数据结构的详细说明

1、整形

Nginx使用ngx_int_t封装有符号整型,使用ngx_uint_t封装无符号整型

ngx_int_t、ngx_uint_t的定义如下:

typedef intptr_t ngx_int_t; 
typedef uintptr_t ngx_uint_t;


2、ngx_str_t

ngx_str_t结构就是字符串。ngx_str_t的定义如下:

typedef struct 
{ 
	size_t len; 
	u_char *data; 
} ngx_str_t;

ngx_str_t只有两个成员,其中data指针指向字符串起始地址,len表示字符串的有效长度。

ngx_str_t的data成员指向的并不是普通的字符串,因为这段字符串未必会以'\0'作为结尾,所以使用时必须根据长度len来使用data成员

例如定义一个ngx_test_str,判断字符串是否是“hello”时,需要执行如下:

ngx_str_t ngx_test_str;
if (0 == ngx_strncmp( ngx_test_str.data, "hello", r->method_name.len) ) 
{...}

任何试图将ngx_str_t的data成员当做字符串来使用的情况,都可能导致内存越界!


3、ngx_list_t

ngx_list_t是Nginx封装的链表容器,它在Nginx中使用得很频繁,例如HTTP的头部就是用ngx_list_t来存储的。

定义:

typedef struct ngx_list_part_s ngx_list_part_t; 
struct ngx_list_part_s 
{ 
	void *elts; 
	ngx_uint_t nelts; 
	ngx_list_part_t *next; 
}; 
typedef struct 
{ 
	ngx_list_part_t *last; 
	ngx_list_part_t part; 
	size_t size;
	ngx_uint_t nalloc; 
	ngx_pool_t *pool; 
} ngx_list_t;

ngx_list_t描述整个链表,而ngx_list_part_t只描述链表的一个元素。

每个链表元素ngx_list_part_t又是一个数组,拥有连续的内存,它既依赖于ngx_list_t里的size和nalloc来表示数组的容量,同时又依靠每个ngx_list_part_t成员中的nelts来表示数组当前已使用了多少容量。因此,ngx_list_t是一个链表容器,而链表中的元素又是一个数组。ngx_list_part_t数组中的元素才是用户想要存储的东西

每个成员的意义:

(1)ngx_list_t

·part:链表的首个数组元素。

·last:指向链表的最后一个数组元素。

·size:通过size限制每一个数组元素的占用的空间大小,也就是用户要存储的一个数据所占用的字节数必须小于或等于size。

·nalloc:nalloc表示每个ngx_list_part_t数组的容量,即最多可存储多少个数据。

·pool:链表中管理内存分配的内存池对象。ngx_list_t中的所有数据都是由ngx_pool_t类型的pool内存池分配的,它们通常都是连续的内存。

(2)ngx_list_part_t

·elts:指向数组的起始地址。

·nelts:表示数组中已经使用了多少个元素。nelts必须小于ngx_list_t结构体中的nalloc。

·next:下一个链表元素ngx_list_part_t的地址。



图中是由3个ngx_list_part_t数组元素组成的ngx_list_t链表的一种内存分布结构,pool内存池为其分配了连续的内存,最前端内存存储的是ngx_list_t结构中的成员,紧接着是第一个ngx_list_part_t结构占用的内存,然后是ngx_list_part_t结构指向的数组,它们一共占用size*nalloc字节,表示数组中拥有nalloc个大小为size的元素。其后面是第2个ngx_list_part_t结构以及它所指向的数组,依此类推。


4、ngx_table_elt_t

ngx_table_elt_t数据结构如下所示:

typedef struct 
{ 
	ngx_uint_t hash; 
	ngx_str_t key; 
	ngx_str_t value; 
	u_char *lowcase_key; 
} ngx_table_elt_t;
ngx_table_elt_t就是一个key/value对,ngx_str_t类型的key、value成员分别存储的是名字、值字符串。

hash用于快速检索头部。lowcase_key指向的是全小写的key字符串。

ngx_table_elt_t是为HTTP头部“量身订制”的,其中key存储头部名称(如Content-Length),value存储对应的值(如“1024”)。


5、 ngx_buf_t

struct ngx_buf_s {
	/*pos通常是用来告诉使用者本次应该从 pos这个位置开始处理内存中的数据,这样设置是因为同一个 ngx_buf_t可能被多次反复处理。*/
    u_char          *pos;
	/*last通常表示有效的内容到此为止*/
    u_char          *last;
	/*file_pos与 file_last的含义与处理内存时的 pos与 last相同, file_pos表示将要处理的文件位置, file_last表示截止的文件位置*/
    off_t            file_pos;
    off_t            file_last;

	/*如果 ngx_buf_t缓冲区用于内存,那么 start指向这段内存的起始地址,end指向指向这段内存的结尾
    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 */
	/*临时内存标志位,为 1时表示数据在内存中且这段内存可以修改*/
    unsigned         temporary:1;

	/*标志位,为 1时表示数据在内存中且这段内存不可以被修改*/
    unsigned         memory:1;

    /*标志位,为 1时表示这段内存是用 mmap系统调用映射过来的,不可以被修改*/
    unsigned         mmap:1;

	/*标志位,为 1时表示可回收*/
    unsigned         recycled:1;
	/*标志位,为 1时表示这段缓冲区处理的是文件而不是内存*/
    unsigned         in_file:1;
	/*标志位,为 1时表示需要执行 flush操作*/
    unsigned         flush:1;
	/*标志位,对于操作这块缓冲区时是否使用同步方式,需谨慎考虑,这可能会阻塞 Nginx进程,
	Nginx中所有操作几乎都是异步的,这是它支持高并发的关键。有些框架代码在 sync为 1时可能会有阻塞的方式进行 I/O操作,
	它的意义视使用它的 Nginx模块而定*/
    unsigned         sync:1;
	/*标志位,表示是否是最后一块缓冲区,因为 ngx_buf_t可以由 ngx_chain_t链表串联起来,
	因此,当 last_buf为 1时,表示当前是最后一块待处理的缓冲区*/
    unsigned         last_buf:1;
	/*标志位,表示是否是 ngx_chain_t中的最后一块缓冲区*/
    unsigned         last_in_chain:1;
	/*标志位,表示是否是最后一个影子缓冲区,与 shadow域配合使用。通常不建议使用它*/
    unsigned         last_shadow:1;
	/*标志位,表示当前缓冲区是否属于临时文件*/
    unsigned         temp_file:1;

    /* STUB */ int   num;
};

6、ngx_chain_t

ngx_chain_t是与ngx_buf_t配合使用的链表数据结构:

typedef struct ngx_chain_s ngx_chain_t;
struct ngx_chain_s
{
         ngx_buf_t*buf;
         ngx_chain_t*next;
};

buf指向当前的ngx_buf_t缓冲区,next则用来指向下一个ngx_chain_t。如果这是最后一个ngx_chain_t,则需要把next置为NULL。

在向用户发送HTTP包体时,就要传入ngx_chain_t链表对象,如果是最后一个ngx_chain_t,那么必须将next置为NULL,否则永远不会发送成功!而且这个请求将一直不会结束(Nginx框架的要求)。



参考: 《深入理解Nginx》  陶辉  机械工业出版社

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值