• Nginx源码分析


    目录解析

    auto   :configure编译的脚本

    html        :默认html

    objs        :执行configure之后产生的

    src          :源码

    conf        :默认配置文件

    contrib        :一些使用工具 e. vim的高亮语法

    man          :帮助文件

    auto文件:

    cc :    #检 各种编译器的脚本

    lib:      #检 各种编译依赖库的脚本

    os:      #检 各种操作系统的脚本
    types: #检 平台相关的基本类型的脚本

     

    src文件

    core                 数据结构定义和核心代码

    event              事件驱动

    http                  http

    mail                 mail模块代码

    misc               辅助代码

    os                    操作系统

    stream             tcp/ip协议处理

    源码特点

    代码风格

    变量名 :函数名全小写 宏大写
    类型名、类型名   函数使用前缀  "ngx_' 宏使用 "NGN_“;
    结构体(struct)使用后缀 “_s",同名的”_t"后缀是等价形式

    代码优化

    自定义一些整数类型实现跨平台编译运行,如ngx_uint_t:

    标志位变量使用了不太常用的“位域”特性(bit field),减少内存占用:

    使用“哨兵”变量(即空对象)表示数组的结束,简化了循环的范围检查,例如ngx_null_command;

    使用宏封装了一些简单的操作,消除函数调用的成本。注意:因为这些宏相当于函数,所以采用了小写的形式,本书之后称它们为“函数宏”。

    面向对象思想

    没有继承概念,只能使用void*指针成员,然后每个“子类”再具体化自己的数据结构,相当于自行实现了C++的对象内存模型;

    没有RTTI(运行时类型信息),只能用一个tag成员来标记类型;

    没有成员函数,只能用原始的函数指针作为结构的成员;

    没有模板和泛型,解决方案同样是void*指针,因为它可以转型为任意类型的数据,但这也造成了理解和使用上的困难;

    没有C++里的引用概念,因此要修改值时只能使用函数形式的宏;

    不支持函数重载,所以有很多实现相同功能、名称近似的函数族;

    大量使用宏(小写形式)来实现类似成员函数调用的“API”,存在容易误用的隐患。

    使用c++开发

    使用类封装Nginx数据结构和相应的操作,增强内聚性;

    使用inline和 static成员函数消除函数调用的成本,用来替代宏;

    尽量使用变量的引用形式而不是指针形式;

    使用函数重载,简化相同功能的函数调用;

    使用模板和泛型技术消灭void*的使用;

    尽量在编译期把类型信息保有起来,避免运行时的类型转换

    ;使用异常简化错误处理

    常量宏保留,不做封装(因为改为enum并不会带来好处)。

    如何使用c++脚本

    首先要明确,gcc不仅能够编译c 代码,也能够编译C++代码,但c与c++程序混合编译时应该使用g++来链接,否则会因为c和C++的编译链接符号不同而链接失败。

    所以我们需要使用文件扩展名区分源码(* .c和* .cpp),单独给gcc增加额外的C++编译选项来编译我们自己的C++代码。如果使用其他第三方C++库(例如 Boost),则可以在configure时用--with-ld-opt参数。

    修改make文件即可

    链接器LINK改用g++;

    增加C++编译选项,为gcc启用c++11标准;

    生成编译命令时用扩展名分支处理c源码和C++源码。

    1. #LINK = $LINK
    2. CXXFLAGS=-std=c++11 -Wall
    3. LINK=g++

    修改静态模板代码

    auto/make :400

    1. ext='echo${ngx_src}|cut -d. -f 2' #get file's suffix
    2. ngx_cxx=$ngx_cc #default that
    3. if{$ext="cpp"};then
    4. nginx_cxx="$ngx_cc \$(CXXFLAGS)"

    修改动态模板代码

    auto/make :642

    1. ext='echo${ngx_srouce}|cut -d. -f 2' #get file's suffix
    2. ngx_cxx=$ngx_cc #default that
    3. if{$ext="cpp"};then
    4. nginx_cxx="$ngx_cc \$(CXXFLAGS)"

    两者都要:

    1. $ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src
    2. $ngx_cxx$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

  • 相关阅读:
    【MySQL】存储引擎
    Redis-数据类型-List
    JS利用循环解决的一些问题
    三天打鱼两天晒网
    uniapp使用@microsoft/signalr(报错“ReferenceError: require is not defined“)
    【毕业设计】基于单片机的墨水屏阅读器(单词卡) - 物联网 嵌入式
    Zookeeper
    基于java(ssm)人事考勤签到管理系统源码(java毕业设计)
    docker 带端口映射启动是报错
    [踩坑专栏]Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletRequest
  • 原文地址:https://blog.csdn.net/qq_62309585/article/details/127628835