码迷,mamicode.com
首页 > 其他好文 > 详细

Nginx源码分析(1)

时间:2015-05-29 18:38:58      阅读:441      评论:0      收藏:0      [点我收藏+]

标签:

Nginx是一个高性能的HTTP服务器,结合Nginx开发从入门到精通一书和Nginx源码学习服务器的高并发处理。

服务器的架构大同小异,而性能的差异主要来自对数据的处理方式上,也即进程模型和事件模型上。一个客户端请求的数据如何进行接受、存储、解析、返回是服务器做的最主要的工作。


最基础的数据结构

C++之所以不被用来写网站是因为,网站的核心是**处理字符串**。而C++的字符串处理实在比较弱,还要不断惦记GC和内存泄漏。

而Nginx首先封装了一下字符串的数据结构和API。定义位于nginx/src/core/nginx_string.h中。

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

Nginx中一个字符串被表示为指针data指示首地址+len指示长度的方式,这种方式唯一定位一个字符串。和标准的glibc API\0的方式标识字符串结束不同,它有很多好处。

  • 通过长度表示字符串长度,减少计算字符串长度的步骤
  • 可以重复引用一段字符串内存,减少不必要的内存分配

这样的表示是不是似曾相识?在Redis的sds中有类似的处理。

struct sdshdr {
    unsigned int len;
    unsigned int free;
    char buf[];
};

再看看它的API,API以宏的方式定义。

#define ngx_string(str)     { sizeof(str) - 1, (u_char *) str }

#define ngx_null_string     { 0, NULL }

#define ngx_str_set(str, text)     (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text

#define ngx_str_null(str)   (str)->len = 0; (str)->data = NULL

第一个宏定义一个nginx的字符串,用法是


int main() { ngx_str_t stringA = ngx_string("Stop"); printf("len: %d \n", stringA.len); printf("address: %p \n", stringA.data); char* p = (char*)("HELLO WORLD"); printf("address: %p \n", p); printf("string %s \n", p); return 0; }

这里直接是宏展开,对结构体进行赋值。先生成了一个临时变量 "stop",然后把临时变量的长度和地址赋值给结构体。 ngx_stringngx_null_string{,}格式的,而结构体只能在初始化时进行整体赋值,因而API只能用于赋值时初始化。还需要注意 str必须是常量字符串,因为 sizeof是以 \0为结束标志的。

打印结果


len: 4 address: 0x8048530 address: 0x804854d string HELLO WORLD

参考

http://tengine.taobao.org/book/chapter_02.html

https://github.com/antirez/redis/blob/unstable/src/sds.h

Nginx源码分析(1)

标签:

原文地址:http://my.oschina.net/lvyi/blog/422284

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!