当前位置: 首页 > news >正文

Ubuntu 下 nginx-1.24.0 源码分析 (1)

main 函数在 

src\core\nginx.c


int ngx_cdecl
main(int argc, char *const *argv)
{ngx_buf_t        *b;ngx_log_t        *log;ngx_uint_t        i;ngx_cycle_t      *cycle, init_cycle;ngx_conf_dump_t  *cd;ngx_core_conf_t  *ccf;ngx_debug_init();

 进入 main 函数

最开始是局部变量的声明

然后是

ngx_debug_init();


接下来是 :

   if (ngx_strerror_init() != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_strerror_init()函数-CSDN博客


 接下来是 :

    if (ngx_get_options(argc, argv) != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_options函数-CSDN博客

当前这次执行的是:

sudo ./nginx

 除了 程序名 没有其他参数

所以 

argc=1 

于是在 ngx_get_options 函数中

static ngx_int_t
ngx_get_options(int argc, char *const *argv)
{u_char     *p;ngx_int_t   i;for (i = 1; i < argc; i++) {p = (u_char *) argv[i];if (*p++ != '-') {ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);return NGX_ERROR;}while (*p) {switch (*p++) {case '?':case 'h':ngx_show_version = 1;ngx_show_help = 1;break;case 'v':ngx_show_version = 1;break;case 'V':ngx_show_version = 1;ngx_show_configure = 1;break;case 't':ngx_test_config = 1;break;case 'T':ngx_test_config = 1;ngx_dump_config = 1;break;case 'q':ngx_quiet_mode = 1;break;case 'p':if (*p) {ngx_prefix = p;goto next;}if (argv[++i]) {ngx_prefix = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-p\" requires directory name");return NGX_ERROR;case 'e':if (*p) {ngx_error_log = p;} else if (argv[++i]) {ngx_error_log = (u_char *) argv[i];} else {ngx_log_stderr(0, "option \"-e\" requires file name");return NGX_ERROR;}if (ngx_strcmp(ngx_error_log, "stderr") == 0) {ngx_error_log = (u_char *) "";}goto next;case 'c':if (*p) {ngx_conf_file = p;goto next;}if (argv[++i]) {ngx_conf_file = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-c\" requires file name");return NGX_ERROR;case 'g':if (*p) {ngx_conf_params = p;goto next;}if (argv[++i]) {ngx_conf_params = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-g\" requires parameter");return NGX_ERROR;case 's':if (*p) {ngx_signal = (char *) p;} else if (argv[++i]) {ngx_signal = argv[i];} else {ngx_log_stderr(0, "option \"-s\" requires parameter");return NGX_ERROR;}if (ngx_strcmp(ngx_signal, "stop") == 0|| ngx_strcmp(ngx_signal, "quit") == 0|| ngx_strcmp(ngx_signal, "reopen") == 0|| ngx_strcmp(ngx_signal, "reload") == 0){ngx_process = NGX_PROCESS_SIGNALLER;goto next;}ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);return NGX_ERROR;default:ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));return NGX_ERROR;}}next:continue;}return NGX_OK;
}

进入不了 for 循环

直接走到

return NGX_OK;

返回到 main 函数中


接下来是 :

if (ngx_show_version) {ngx_show_version_info();if (!ngx_test_config) {return 0;}}

ngx_show_version 未设置,此时是 0

于是跳过这段代码


接下来是 :

/* TODO */ ngx_max_sockets = -1;

初始化全局变量 ngx_max_sockets

ngx_max_sockets 是一个全局变量,用于存储 Nginx 能够处理的最大文件描述符(socket)数量。

文件描述符是操作系统用于管理打开的文件、socket 等资源的标识符。Nginx 作为一个高性能的 Web 服务器,需要处理大量的并发连接,因此文件描述符的数量对性能有重要影响

初始值为 -1 的意义

  • 将 ngx_max_sockets 初始化为 -1 表示在程序启动时,还没有确定实际的最大文件描述符数量。

  • -1 通常用作一个初始值或无效值,表示该变量尚未被正确初始化或配置

  • 在后续的代码中,Nginx 会根据操作系统的限制和配置文件中的设置来更新 ngx_max_sockets 的值。


接下来是 :

ngx_time_init();

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_time_init 函数-CSDN博客


接下来是 :

#if (NGX_PCRE)ngx_regex_init();
#endif

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_regex_init 函数-CSDN博客


接下来是 :

    ngx_pid = ngx_getpid();ngx_parent = ngx_getppid();

获取当前进程的进程ID(ngx_pid)和父进程的进程ID(ngx_parent)。

这在后续的进程管理中很有用。

src/os/unix/ngx_process.h 中:

#define ngx_getpid   getpid
#define ngx_getppid  getppid

getpid 和 getppid 是 C 语言中用于获取进程 ID 的函数,定义在 <unistd.h> 头文件中

getpid():获取当前进程的进程ID
getppid():获取当前进程的父进程ID

父进程是创建当前进程的进程(如通过fork())。
若父进程终止,子进程的PPID会被重置为init进程(PID=1)


接下来是: 

    log = ngx_log_init(ngx_prefix, ngx_error_log);if (log == NULL) {return 1;}

 Ubuntu 下 nginx-1.24.0 源码分析 - ngx_log_init 函数-CSDN博客

此次调用 ngx_log_init 

prefix 和 error_log 都还没有设置此时还是 null

进入 ngx_log_init 

首先是

ngx_log_t *
ngx_log_init(u_char *prefix, u_char *error_log)
{u_char  *p, *name;size_t   nlen, plen;ngx_log.file = &ngx_log_file;ngx_log.log_level = NGX_LOG_NOTICE;
  • 将全局日志对象 ngx_log 的文件指针指向 ngx_log_file

  • 设置默认日志级别为 NGX_LOG_NOTICE(通知级别)

    if (error_log == NULL) {error_log = (u_char *) NGX_ERROR_LOG_PATH;}name = error_log;nlen = ngx_strlen(name);

此时 error_log 还是null

于是进入这个 if 条件中

把默认值 NGX_ERROR_LOG_PATH 赋值给 error_log 

这个默认值是在 执行configure命令时定义的一个宏,它的值由 configure 命令的配置项 --error-log-path 指定

    if (nlen == 0) {ngx_log_file.fd = ngx_stderr;return &ngx_log;}p = NULL;

nlen 不是0

跳过这个 if 条件

if (name[0] != '/') {

检查路径是否以 / 开头

是以 开头

所以当前 name 已经是绝对路径了,不需要拼接前缀

ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,NGX_FILE_CREATE_OR_OPEN,NGX_FILE_DEFAULT_ACCESS);

以追加的方式打开 name 指向的 日志文件 

此时返回的 fd 是 4

    if (ngx_log_file.fd == NGX_INVALID_FILE) {ngx_log_stderr(ngx_errno,"[alert] could not open error log file: "ngx_open_file_n " \"%s\" failed", name);

 NGX_INVALID_FILE 的值是 -1 无效的文件描述符,表示上一步的打开文件失败

现在这个条件不成立,跳过这段代码

   if (p) {ngx_free(p);}return &ngx_log;

由于之前条件不成立,所以 没有用到 p

最后返回 ngx_log 的地址


回到 main 函数中

接下来是: 

ngx_ssl_init(log);

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_ssl_init 函数-CSDN博客


接下来是: 

  ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));

把 init_cycle 的每个字节都初始化为 0

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cycle_t 类型-CSDN博客

    init_cycle.log = log;

将之前 初始化的 日志对象的地址 记录在 log 字段

    ngx_cycle = &init_cycle;

现在 ngx_cycle 是指向 init_cycle 的指针了


   init_cycle.pool = ngx_create_pool(1024, log);

创建一个内存池要求的内存大小是 1024 字节,然后将地址记录到 init_cycle pool 字段进行管理

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_create_pool函数-CSDN博客

进入 ngx_create_pool

ngx_pool_t *
ngx_create_pool(size_t size, ngx_log_t *log)
{ngx_pool_t  *p;p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);if (p == NULL) {return NULL;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_memalign函数-CSDN博客

 使用 ngx_memalign 来分配内存

NGX_POOL_ALIGNMENT 是要求的对齐边界,值为 16

进入 ngx_memalign

void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{void  *p;int    err;err = posix_memalign(&p, alignment, size);

调用 posix_memalign 来分配一块对齐的内存

posix_memalign 函数-CSDN博客

 此次返回值为 0

也就是分配内存成功了

p=0x5aa55f9765a0

这个地址是按 16 对齐的

if (err) {ngx_log_error(NGX_LOG_EMERG, log, err,"posix_memalign(%uz, %uz) failed", alignment, size);p = NULL;}

条件不成立,跳过这段代码

return p;

把分配的地址返回到

ngx_create_pool 函数中


 回到 ngx_create_pool

接下来是:

   if (p == NULL) {return NULL;}

条件不成立,跳过这段代码

    p->d.last = (u_char *) p + sizeof(ngx_pool_t);p->d.end = (u_char *) p + size;p->d.next = NULL;p->d.failed = 0;size = size - sizeof(ngx_pool_t);p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;p->current = p;p->chain = NULL;p->large = NULL;p->cleanup = NULL;p->log = log;return p;

赋值然后返回 内存池 地址

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_create_pool函数-CSDN博客

当前 size = 944 , NGX_MAX_ALLOC_FROM_POOL = -1
所以 p->max=944


回到 main 函数中

接下来是:

   if (init_cycle.pool == NULL) {return 1;}

条件不成立,跳过这段代码

   if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_save_argv函数-CSDN博客


    if (ngx_process_options(&init_cycle) != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_process_options-CSDN博客

 进入 ngx_process_options

static ngx_int_t
ngx_process_options(ngx_cycle_t *cycle)
{u_char  *p;size_t   len;if (ngx_prefix) {

ngx_prefix 还是 null

所以跳过这个 if 代码段进入 else

接下来是:

ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);

将 默认的配置文件路径前缀设置给 cycle->conf_prefix

ngx_str_set(&cycle->prefix, NGX_PREFIX);

将 默认的路径前缀设置给 cycle->prefix

    if (ngx_conf_file) {cycle->conf_file.len = ngx_strlen(ngx_conf_file);cycle->conf_file.data = ngx_conf_file;} else {ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);}

此次启动没有指定 配置文件路径

所以 ngx_conf_file 在这里还是 null

进入 else 中,将 默认的配置文件路径设置给 cycle->conf_file 进行管理

接下来是:

    if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {return NGX_ERROR;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_full_name 函数-CSDN博客

cycle->conf_file 保存的配置文件路径可能是 相对路径,需要 调用 ngx_conf_full_name  来拼接路径前缀 然后形成完成的路径

进入 ngx_conf_full_name 中

ngx_int_t
ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
{ngx_str_t  *prefix;prefix = conf_prefix ? &cycle->conf_prefix : &cycle->prefix;return ngx_get_full_name(cycle->pool, prefix, name);
}

这里传进来的 conf_prefix 的值是 0

所以 prefix =  &cycle->prefix; 选择 cycle->prefix (/usr/local/nginx/) 作为配置文件路径前缀

然后调用 ngx_get_full_name 来拼接路径

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_full_name 函数-CSDN博客

进入 ngx_get_full_name

ngx_int_t
ngx_get_full_name(ngx_pool_t *pool, ngx_str_t *prefix, ngx_str_t *name)
{size_t      len;u_char     *p, *n;ngx_int_t   rc;rc = ngx_test_full_name(name);if (rc == NGX_OK) {return rc;}

调用 ngx_test_full_name 来判断 name (/home/wsd/桌面/nginx/conf/nginx.conf) 是否是完整的路径

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_test_full_name-CSDN博客

进入 ngx_test_full_name

static ngx_int_t
ngx_test_full_name(ngx_str_t *name)
{
#if (NGX_WIN32)u_char  c0, c1;c0 = name->data[0];if (name->len < 2) {if (c0 == '/') {return 2;}return NGX_DECLINED;}c1 = name->data[1];if (c1 == ':') {c0 |= 0x20;if ((c0 >= 'a' && c0 <= 'z')) {return NGX_OK;}return NGX_DECLINED;}if (c1 == '/') {return NGX_OK;}if (c0 == '/') {return 2;}return NGX_DECLINED;#elseif (name->data[0] == '/') {return NGX_OK;}return NGX_DECLINED;#endif
}

 当前环境是 Ubuntu  #if (NGX_WIN32) 不成立

所以接下来执行的是:

    if (name->data[0] == '/') {return NGX_OK;}return NGX_DECLINED;

条件成立 name  的第一个字符是

被认为是 绝对路径

返回 NGX_OK


回到 ngx_get_full_name

   rc = ngx_test_full_name(name);if (rc == NGX_OK) {return rc;}

rc 得到的返回值是 NGX_OK

条件成立,把这个 NGX_OK 返回到 ngx_conf_full_name 

return ngx_get_full_name(cycle->pool, prefix, name);

这个结果继续向上返回到 ngx_process_options


回到 ngx_process_options

接下来是:

if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {return NGX_ERROR;}

于是 这里 调用 ngx_conf_full_name 得到 返回值 NGX_OK

条件不成立

接下来是:

   for (p = cycle->conf_file.data + cycle->conf_file.len - 1;p > cycle->conf_file.data;p--){if (ngx_path_separator(*p)) {cycle->conf_prefix.len = p - cycle->conf_file.data + 1;cycle->conf_prefix.data = cycle->conf_file.data;break;}}

cycle->conf_file.data 是配置文件路径,

cycle->conf_file.data + cycle->conf_file.len - 1 指向这个路径字符串的最后一个字节

从最后一个字符向第一个字符遍历

if (ngx_path_separator(*p)) { 判断当前这个字符是否是分隔符 /

这个 分隔符后面是 配置文件的文件名,前面是配置文件的目录

将 cycle->conf_file.data 的地址赋给cycle->conf_prefix.data

从这个地址开始 len 个字符是 配置文件所在的目录

于是 

cycle->conf_file.data(0x5bfbfeaf3e50) = cycle->conf_prefix.data(0x5bfbfeaf3e50)

这2个地址一样

cycle->conf_file.len=38
cycle->conf_file.data=/home/wsd/桌面/nginx/conf/nginx.conf

cycle->conf_prefix.len=28
cycle->conf_prefix.data=/home/wsd/桌面/nginx/conf/

就是 cycle->conf_file.data 的前 28 个字节

接下来是:

if (ngx_error_log) {cycle->error_log.len = ngx_strlen(ngx_error_log);cycle->error_log.data = ngx_error_log;} else {ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH);}

当前 ngx_error_log=null  还没有设置它

所以进入 else

把 默认值 NGX_ERROR_LOG_PATH(/home/wsd/桌面/nginx/LOG/error.log)

设置给 cycle->error_log             

       

接下来是:

    if (ngx_conf_params) {cycle->conf_param.len = ngx_strlen(ngx_conf_params);cycle->conf_param.data = ngx_conf_params;}

 ngx_conf_params 没有设置是 null

所以跳过这段代码

if (ngx_test_config) {cycle->log->log_level = NGX_LOG_INFO;}

ngx_test_config 0

所以跳过这段代码

  return NGX_OK;

返回结果


回到 main 函数中

接下来是:

   if (ngx_os_init(log) != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_init 函数-CSDN博客

 进入 ngx_os_init

ngx_int_t
ngx_os_init(ngx_log_t *log)
{ngx_time_t  *tp;ngx_uint_t   n;
#if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)long         size;
#endif#if (NGX_HAVE_OS_SPECIFIC_INIT)if (ngx_os_specific_init(log) != NGX_OK) {return NGX_ERROR;}
#endif

调用 ngx_os_specific_init 函数

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_specific_init函数-CSDN博客

 进入 ngx_os_specific_init

ngx_int_t
ngx_os_specific_init(ngx_log_t *log)
{struct utsname  u;if (uname(&u) == -1) {ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "uname() failed");return NGX_ERROR;}

调用 uname 获取系统信息 

这次获得的系统信息如下:

// 操作系统名称

u.sysname=Linux 

//主机名          
u.nodename=wsd-vm

//操作系统发行版本
u.release=6.8.0-52-generic

// 操作系统版本信息
u.version=#53~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jan 15 19:18:46 UTC 2

// 硬件架构
u.machine=x86_64

接下来是:

    (void) ngx_cpystrn(ngx_linux_kern_ostype, (u_char *) u.sysname,sizeof(ngx_linux_kern_ostype));(void) ngx_cpystrn(ngx_linux_kern_osrelease, (u_char *) u.release,sizeof(ngx_linux_kern_osrelease));

复制 u.sysname u.release 存储到全局变量 ngx_linux_kern_ostype 和 ngx_linux_kern_osrelease

   ngx_os_io = ngx_linux_io;return NGX_OK;

设置 ngx_os_io 

然后返回结果


回到 ngx_os_init

接下来是:

   if (ngx_init_setproctitle(log) != NGX_OK) {return NGX_ERROR;}

调用 ngx_init_setproctitle

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_setproctitle函数-CSDN博客

 进入 ngx_init_setproctitle

ngx_int_t
ngx_init_setproctitle(ngx_log_t *log)
{u_char      *p;size_t       size;ngx_uint_t   i;size = 0;for (i = 0; environ[i]; i++) {size += ngx_strlen(environ[i]) + 1;}

遍历 环境变量

ngx_strlen(environ[i]) + 1;

是当前这个环境变量占用的内存字节数量(字符串长度 + 字符串结束标志 '\0')

累加到 size 中,最终 size 的值是整个环境变量占据的字节数量

这次的执行情况:

i=0
environ[0]="COLORTERM=truecolor"
ngx_strlen(environ[0]) + 1  =20
size=20

i=1
environ[1]="LANGUAGE=zh_CN:en"
ngx_strlen(environ[1]) + 1  =18
size=38

i=2
environ[2]="LC_ADDRESS=zh_CN.UTF-8"
ngx_strlen(environ[2]) + 1  =23
size=61

i=3
environ[3]="LC_NAME=zh_CN.UTF-8"
ngx_strlen(environ[3]) + 1  =20
size=81

i=4
environ[4]="LC_MONETARY=zh_CN.UTF-8"
ngx_strlen(environ[4]) + 1  =24
size=105

i=5
environ[5]="XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.SUZ122"
ngx_strlen(environ[5]) + 1  =54
size=159

i=6
environ[6]="LC_PAPER=zh_CN.UTF-8"
ngx_strlen(environ[6]) + 1  =21
size=180

i=7
environ[7]="LANG=zh_CN.UTF-8"
ngx_strlen(environ[7]) + 1  =17
size=197

i=8
environ[8]="LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:"
ngx_strlen(environ[8]) + 1  =1519
size=1716

i=9
environ[9]="XDG_CURRENT_DESKTOP=ubuntu:GNOME"
ngx_strlen(environ[9]) + 1  =33
size=1749

i=10
environ[10]="TERM=xterm-256color"
ngx_strlen(environ[10]) + 1  =20
size=1769

i=11
environ[11]="LC_IDENTIFICATION=zh_CN.UTF-8"
ngx_strlen(environ[11]) + 1  =30
size=1799

i=12
environ[12]="DISPLAY=:0"
ngx_strlen(environ[12]) + 1  =11
size=1810

i=13
environ[13]="LC_TELEPHONE=zh_CN.UTF-8"
ngx_strlen(environ[13]) + 1  =25
size=1835

i=14
environ[14]="LC_MEASUREMENT=zh_CN.UTF-8"
ngx_strlen(environ[14]) + 1  =27
size=1862

i=15
environ[15]="LC_TIME=zh_CN.UTF-8"
ngx_strlen(environ[15]) + 1  =20
size=1882

i=16
environ[16]="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
ngx_strlen(environ[16]) + 1  =76
size=1958

i=17
environ[17]="LC_NUMERIC=zh_CN.UTF-8"
ngx_strlen(environ[17]) + 1  =23
size=1981

i=18
environ[18]="MAIL=/var/mail/root"
ngx_strlen(environ[18]) + 1  =20
size=2001

i=19
environ[19]="LOGNAME=root"
ngx_strlen(environ[19]) + 1  =13
size=2014

i=20
environ[20]="USER=root"
ngx_strlen(environ[20]) + 1  =10
size=2024

i=21
environ[21]="HOME=/root"
ngx_strlen(environ[21]) + 1  =11
size=2035

i=22
environ[22]="SHELL=/bin/bash"
ngx_strlen(environ[22]) + 1  =16
size=2051

i=23
environ[23]="SUDO_COMMAND=./nginx"
ngx_strlen(environ[23]) + 1  =21
size=2072

i=24
environ[24]="SUDO_USER=wsd"
ngx_strlen(environ[24]) + 1  =14
size=2086

i=25
environ[25]="SUDO_UID=1000"
ngx_strlen(environ[25]) + 1  =14
size=2100

i=26
environ[26]="SUDO_GID=1000"
ngx_strlen(environ[26]) + 1  =14
size=2114

 接下来是:

   p = ngx_alloc(size, log);if (p == NULL) {return NGX_ERROR;}

为环境变量分配内存,环境变量将要迁移到新分配的内存中

此次运行的情况:

p = ngx_alloc(size=2114, log);

p=0x654273b10f20

  接下来是:

    ngx_os_argv_last = ngx_os_argv[0];

ngx_os_argv_last 将用于标记命令行参数可用的边界

ngx_os_argv[0] 是存储参数的那片内存的首地址

 接下来是:

for (i = 0; ngx_os_argv[i]; i++) {if (ngx_os_argv_last == ngx_os_argv[i]) {ngx_os_argv_last = ngx_os_argv[i] + ngx_strlen(ngx_os_argv[i]) + 1;}}

循环,每次循环获取下一个参数的首地址,直到这个地址为 null,

null 是标记,意味着到此为止,后面没有更多的参数了

ngx_os_argv[i] 是参数首地址,ngx_strlen(ngx_os_argv[i])  是参数的长度,最后再 + 1,就越过了这个参数的最后一个字节成了下一个参数的最后一个字节

所以下一次循环时 ngx_os_argv[i] 是下一个参数的首地址 等于 上一次循环被重新赋值的 ngx_os_argv_last 

这样 ngx_os_argv_last 的值在不断的向后移动,直到它等于存贮参数的内存的最后一个字节的下一个字节(也是环境变量的第一个字节)

此次的执行情况是:

i=0
ngx_os_argv_last(0x7ffecc4747a6) == ngx_os_argv[0](0x7ffecc4747a6)  
ngx_os_argv_last(0x7ffecc4747ae) = ngx_os_argv[0] + ngx_strlen(ngx_os_argv[0])(7) + 1;

因为此次运行时没有给命令行参数,所以 只有一个参数,也就是运行的程序名

 接下来是:

for (i = 0; environ[i]; i++) {if (ngx_os_argv_last == environ[i]) {size = ngx_strlen(environ[i]) + 1;ngx_os_argv_last = environ[i] + size;ngx_cpystrn(p, (u_char *) environ[i], size);environ[i] = (char *) p;p += size;}}

现在 ngx_os_argv_last 等于环境变量的首地址

循环逻辑与上一个循环相同

ngx_os_argv_last 逐渐向后移

每次遍历还会将 环境变量依次迁移到新分配的内存

此次的运行情况:

i=0
ngx_os_argv_last(=0x7ffde3e967ae) == environ[0](=0x7ffde3e967ae)
size(=20) = ngx_strlen(environ[0])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e967c2) = environ[0](=0x7ffde3e967ae) + size(=20);
ngx_cpystrn(0x62a807451f20, 0x7ffde3e967ae, 20);
environ[0](=0x62a807451f20) = (char *) p(=0x62a807451f20);
 p(=0x62a807451f34) += size(=20); 

i=1
ngx_os_argv_last(=0x7ffde3e967c2) == environ[1](=0x7ffde3e967c2)
size(=18) = ngx_strlen(environ[1])(=17) + 1;
ngx_os_argv_last(=0x7ffde3e967d4) = environ[1](=0x7ffde3e967c2) + size(=18);
ngx_cpystrn(0x62a807451f34, 0x7ffde3e967c2, 18);
environ[1](=0x62a807451f34) = (char *) p(=0x62a807451f34);
 p(=0x62a807451f46) += size(=18); 

i=2
ngx_os_argv_last(=0x7ffde3e967d4) == environ[2](=0x7ffde3e967d4)
size(=23) = ngx_strlen(environ[2])(=22) + 1;
ngx_os_argv_last(=0x7ffde3e967eb) = environ[2](=0x7ffde3e967d4) + size(=23);
ngx_cpystrn(0x62a807451f46, 0x7ffde3e967d4, 23);
environ[2](=0x62a807451f46) = (char *) p(=0x62a807451f46);
 p(=0x62a807451f5d) += size(=23); 

i=3
ngx_os_argv_last(=0x7ffde3e967eb) == environ[3](=0x7ffde3e967eb)
size(=20) = ngx_strlen(environ[3])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e967ff) = environ[3](=0x7ffde3e967eb) + size(=20);
ngx_cpystrn(0x62a807451f5d, 0x7ffde3e967eb, 20);
environ[3](=0x62a807451f5d) = (char *) p(=0x62a807451f5d);
 p(=0x62a807451f71) += size(=20); 

i=4
ngx_os_argv_last(=0x7ffde3e967ff) == environ[4](=0x7ffde3e967ff)
size(=24) = ngx_strlen(environ[4])(=23) + 1;
ngx_os_argv_last(=0x7ffde3e96817) = environ[4](=0x7ffde3e967ff) + size(=24);
ngx_cpystrn(0x62a807451f71, 0x7ffde3e967ff, 24);
environ[4](=0x62a807451f71) = (char *) p(=0x62a807451f71);
 p(=0x62a807451f89) += size(=24); 

i=5
ngx_os_argv_last(=0x7ffde3e96817) == environ[5](=0x7ffde3e96817)
size(=54) = ngx_strlen(environ[5])(=53) + 1;
ngx_os_argv_last(=0x7ffde3e9684d) = environ[5](=0x7ffde3e96817) + size(=54);
ngx_cpystrn(0x62a807451f89, 0x7ffde3e96817, 54);
environ[5](=0x62a807451f89) = (char *) p(=0x62a807451f89);
 p(=0x62a807451fbf) += size(=54); 

i=6
ngx_os_argv_last(=0x7ffde3e9684d) == environ[6](=0x7ffde3e9684d)
size(=21) = ngx_strlen(environ[6])(=20) + 1;
ngx_os_argv_last(=0x7ffde3e96862) = environ[6](=0x7ffde3e9684d) + size(=21);
ngx_cpystrn(0x62a807451fbf, 0x7ffde3e9684d, 21);
environ[6](=0x62a807451fbf) = (char *) p(=0x62a807451fbf);
 p(=0x62a807451fd4) += size(=21); 

i=7
ngx_os_argv_last(=0x7ffde3e96862) == environ[7](=0x7ffde3e96862)
size(=17) = ngx_strlen(environ[7])(=16) + 1;
ngx_os_argv_last(=0x7ffde3e96873) = environ[7](=0x7ffde3e96862) + size(=17);
ngx_cpystrn(0x62a807451fd4, 0x7ffde3e96862, 17);
environ[7](=0x62a807451fd4) = (char *) p(=0x62a807451fd4);
 p(=0x62a807451fe5) += size(=17); 

i=8
ngx_os_argv_last(=0x7ffde3e96873) == environ[8](=0x7ffde3e96873)
size(=1519) = ngx_strlen(environ[8])(=1518) + 1;
ngx_os_argv_last(=0x7ffde3e96e62) = environ[8](=0x7ffde3e96873) + size(=1519);
ngx_cpystrn(0x62a807451fe5, 0x7ffde3e96873, 1519);
environ[8](=0x62a807451fe5) = (char *) p(=0x62a807451fe5);
 p(=0x62a8074525d4) += size(=1519); 

i=9
ngx_os_argv_last(=0x7ffde3e96e62) == environ[9](=0x7ffde3e96e62)
size(=33) = ngx_strlen(environ[9])(=32) + 1;
ngx_os_argv_last(=0x7ffde3e96e83) = environ[9](=0x7ffde3e96e62) + size(=33);
ngx_cpystrn(0x62a8074525d4, 0x7ffde3e96e62, 33);
environ[9](=0x62a8074525d4) = (char *) p(=0x62a8074525d4);
 p(=0x62a8074525f5) += size(=33); 

i=10
ngx_os_argv_last(=0x7ffde3e96e83) == environ[10](=0x7ffde3e96e83)
size(=20) = ngx_strlen(environ[10])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e96e97) = environ[10](=0x7ffde3e96e83) + size(=20);
ngx_cpystrn(0x62a8074525f5, 0x7ffde3e96e83, 20);
environ[10](=0x62a8074525f5) = (char *) p(=0x62a8074525f5);
 p(=0x62a807452609) += size(=20); 

i=11
ngx_os_argv_last(=0x7ffde3e96e97) == environ[11](=0x7ffde3e96e97)
size(=30) = ngx_strlen(environ[11])(=29) + 1;
ngx_os_argv_last(=0x7ffde3e96eb5) = environ[11](=0x7ffde3e96e97) + size(=30);
ngx_cpystrn(0x62a807452609, 0x7ffde3e96e97, 30);
environ[11](=0x62a807452609) = (char *) p(=0x62a807452609);
 p(=0x62a807452627) += size(=30); 

i=12
ngx_os_argv_last(=0x7ffde3e96eb5) == environ[12](=0x7ffde3e96eb5)
size(=11) = ngx_strlen(environ[12])(=10) + 1;
ngx_os_argv_last(=0x7ffde3e96ec0) = environ[12](=0x7ffde3e96eb5) + size(=11);
ngx_cpystrn(0x62a807452627, 0x7ffde3e96eb5, 11);
environ[12](=0x62a807452627) = (char *) p(=0x62a807452627);
 p(=0x62a807452632) += size(=11); 

i=13
ngx_os_argv_last(=0x7ffde3e96ec0) == environ[13](=0x7ffde3e96ec0)
size(=25) = ngx_strlen(environ[13])(=24) + 1;
ngx_os_argv_last(=0x7ffde3e96ed9) = environ[13](=0x7ffde3e96ec0) + size(=25);
ngx_cpystrn(0x62a807452632, 0x7ffde3e96ec0, 25);
environ[13](=0x62a807452632) = (char *) p(=0x62a807452632);
 p(=0x62a80745264b) += size(=25); 

i=14
ngx_os_argv_last(=0x7ffde3e96ed9) == environ[14](=0x7ffde3e96ed9)
size(=27) = ngx_strlen(environ[14])(=26) + 1;
ngx_os_argv_last(=0x7ffde3e96ef4) = environ[14](=0x7ffde3e96ed9) + size(=27);
ngx_cpystrn(0x62a80745264b, 0x7ffde3e96ed9, 27);
environ[14](=0x62a80745264b) = (char *) p(=0x62a80745264b);
 p(=0x62a807452666) += size(=27); 

i=15
ngx_os_argv_last(=0x7ffde3e96ef4) == environ[15](=0x7ffde3e96ef4)
size(=20) = ngx_strlen(environ[15])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e96f08) = environ[15](=0x7ffde3e96ef4) + size(=20);
ngx_cpystrn(0x62a807452666, 0x7ffde3e96ef4, 20);
environ[15](=0x62a807452666) = (char *) p(=0x62a807452666);
 p(=0x62a80745267a) += size(=20); 

i=16
ngx_os_argv_last(=0x7ffde3e96f08) == environ[16](=0x7ffde3e96f08)
size(=76) = ngx_strlen(environ[16])(=75) + 1;
ngx_os_argv_last(=0x7ffde3e96f54) = environ[16](=0x7ffde3e96f08) + size(=76);
ngx_cpystrn(0x62a80745267a, 0x7ffde3e96f08, 76);
environ[16](=0x62a80745267a) = (char *) p(=0x62a80745267a);
 p(=0x62a8074526c6) += size(=76); 

i=17
ngx_os_argv_last(=0x7ffde3e96f54) == environ[17](=0x7ffde3e96f54)
size(=23) = ngx_strlen(environ[17])(=22) + 1;
ngx_os_argv_last(=0x7ffde3e96f6b) = environ[17](=0x7ffde3e96f54) + size(=23);
ngx_cpystrn(0x62a8074526c6, 0x7ffde3e96f54, 23);
environ[17](=0x62a8074526c6) = (char *) p(=0x62a8074526c6);
 p(=0x62a8074526dd) += size(=23); 

i=18
ngx_os_argv_last(=0x7ffde3e96f6b) == environ[18](=0x7ffde3e96f6b)
size(=20) = ngx_strlen(environ[18])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e96f7f) = environ[18](=0x7ffde3e96f6b) + size(=20);
ngx_cpystrn(0x62a8074526dd, 0x7ffde3e96f6b, 20);
environ[18](=0x62a8074526dd) = (char *) p(=0x62a8074526dd);
 p(=0x62a8074526f1) += size(=20); 

i=19
ngx_os_argv_last(=0x7ffde3e96f7f) == environ[19](=0x7ffde3e96f7f)
size(=13) = ngx_strlen(environ[19])(=12) + 1;
ngx_os_argv_last(=0x7ffde3e96f8c) = environ[19](=0x7ffde3e96f7f) + size(=13);
ngx_cpystrn(0x62a8074526f1, 0x7ffde3e96f7f, 13);
environ[19](=0x62a8074526f1) = (char *) p(=0x62a8074526f1);
 p(=0x62a8074526fe) += size(=13); 

i=20
ngx_os_argv_last(=0x7ffde3e96f8c) == environ[20](=0x7ffde3e96f8c)
size(=10) = ngx_strlen(environ[20])(=9) + 1;
ngx_os_argv_last(=0x7ffde3e96f96) = environ[20](=0x7ffde3e96f8c) + size(=10);
ngx_cpystrn(0x62a8074526fe, 0x7ffde3e96f8c, 10);
environ[20](=0x62a8074526fe) = (char *) p(=0x62a8074526fe);
 p(=0x62a807452708) += size(=10); 

i=21
ngx_os_argv_last(=0x7ffde3e96f96) == environ[21](=0x7ffde3e96f96)
size(=11) = ngx_strlen(environ[21])(=10) + 1;
ngx_os_argv_last(=0x7ffde3e96fa1) = environ[21](=0x7ffde3e96f96) + size(=11);
ngx_cpystrn(0x62a807452708, 0x7ffde3e96f96, 11);
environ[21](=0x62a807452708) = (char *) p(=0x62a807452708);
 p(=0x62a807452713) += size(=11); 

i=22
ngx_os_argv_last(=0x7ffde3e96fa1) == environ[22](=0x7ffde3e96fa1)
size(=16) = ngx_strlen(environ[22])(=15) + 1;
ngx_os_argv_last(=0x7ffde3e96fb1) = environ[22](=0x7ffde3e96fa1) + size(=16);
ngx_cpystrn(0x62a807452713, 0x7ffde3e96fa1, 16);
environ[22](=0x62a807452713) = (char *) p(=0x62a807452713);
 p(=0x62a807452723) += size(=16); 

i=23
ngx_os_argv_last(=0x7ffde3e96fb1) == environ[23](=0x7ffde3e96fb1)
size(=21) = ngx_strlen(environ[23])(=20) + 1;
ngx_os_argv_last(=0x7ffde3e96fc6) = environ[23](=0x7ffde3e96fb1) + size(=21);
ngx_cpystrn(0x62a807452723, 0x7ffde3e96fb1, 21);
environ[23](=0x62a807452723) = (char *) p(=0x62a807452723);
 p(=0x62a807452738) += size(=21); 

i=24
ngx_os_argv_last(=0x7ffde3e96fc6) == environ[24](=0x7ffde3e96fc6)
size(=14) = ngx_strlen(environ[24])(=13) + 1;
ngx_os_argv_last(=0x7ffde3e96fd4) = environ[24](=0x7ffde3e96fc6) + size(=14);
ngx_cpystrn(0x62a807452738, 0x7ffde3e96fc6, 14);
environ[24](=0x62a807452738) = (char *) p(=0x62a807452738);
 p(=0x62a807452746) += size(=14); 

i=25
ngx_os_argv_last(=0x7ffde3e96fd4) == environ[25](=0x7ffde3e96fd4)
size(=14) = ngx_strlen(environ[25])(=13) + 1;
ngx_os_argv_last(=0x7ffde3e96fe2) = environ[25](=0x7ffde3e96fd4) + size(=14);
ngx_cpystrn(0x62a807452746, 0x7ffde3e96fd4, 14);
environ[25](=0x62a807452746) = (char *) p(=0x62a807452746);
 p(=0x62a807452754) += size(=14); 

i=26
ngx_os_argv_last(=0x7ffde3e96fe2) == environ[26](=0x7ffde3e96fe2)
size(=14) = ngx_strlen(environ[26])(=13) + 1;
ngx_os_argv_last(=0x7ffde3e96ff0) = environ[26](=0x7ffde3e96fe2) + size(=14);
ngx_cpystrn(0x62a807452754, 0x7ffde3e96fe2, 14);
environ[26](=0x62a807452754) = (char *) p(=0x62a807452754);
 p(=0x62a807452762) += size(=14); 

  接下来是:

ngx_os_argv_last--;return NGX_OK;

 ngx_os_argv_last 的值 -1,指向原来存放环境变量的那片内存的最后一个字节

然后返回


 回到 ngx_os_init

  接下来是:

ngx_pagesize = getpagesize();

 获取 当前系统一页的大小是多少字节

此次的情况

ngx_pagesize=4096

   ngx_cacheline_size = NGX_CPU_CACHE_LINE;

 存储 CPU 缓存行大小,默认值为 NGX_CPU_CACHE_LINE

目前的情况:

 ngx_cacheline_size=64

for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }

计算页面大小的对数(ngx_pagesize_shift),即页面大小是 2 的多少次幂。

例如,4KB 的页面大小对应 ngx_pagesize_shift = 12

此次的情况:

ngx_pagesize_shift=12

  if (ngx_ncpu == 0) {ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);}

 获取当前系统在线的 CPU 核心数

此次的情况是:

ngx_ncpu=2

    if (ngx_ncpu < 1) {ngx_ncpu = 1;}

条件不成立,跳过这段代码

    size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);if (size > 0) {ngx_cacheline_size = size;}

sysconf(_SC_LEVEL1_DCACHE_LINESIZE) :获取一级缓存行大小

成功就更新 ngx_cacheline_size ,之前的值是默认值

此次的情况:

获取成功,但获得的值和默认值一样

 ngx_cacheline_size=64

  接下来是:

    ngx_cpuinfo();

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cpuinfo 函数-CSDN博客

接下来是:

    if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {ngx_log_error(NGX_LOG_ALERT, log, errno,"getrlimit(RLIMIT_NOFILE) failed");return NGX_ERROR;}ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;

 获取文件描述符数量的限制

此次的情况是:

ngx_max_sockets=1024

#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)ngx_inherited_nonblocking = 1;
#elsengx_inherited_nonblocking = 0;
#endif

ngx_inherited_nonblocking :全局变量,指示当前环境是否支持继承非阻塞套接字 

当前情况:

ngx_inherited_nonblocking=1

   tp = ngx_timeofday();srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);return NGX_OK;

获取当前的时间缓存 用来 设置随机数种子 

返回 NGX_OK


回到 main 函数中

接下来是:

    if (ngx_crc32_table_init() != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_crc32_table_init 函数-CSDN博客

   ngx_slab_sizes_init();

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_slab_sizes_init 函数-CSDN博客

进入 ngx_slab_sizes_init

void
ngx_slab_sizes_init(void)
{ngx_uint_t  n;ngx_slab_max_size = ngx_pagesize / 2;ngx_slab_exact_size = ngx_pagesize / (8 * sizeof(uintptr_t));for (n = ngx_slab_exact_size; n >>= 1; ngx_slab_exact_shift++) {/* void */}
}

此次的情况是: 

ngx_slab_max_size=2048
ngx_slab_exact_size=64
ngx_slab_exact_shift=6


回到 main 函数中

接下来是:

   if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_add_inherited_sockets函数-CSDN博客

进入 ngx_add_inherited_sockets

static ngx_int_t
ngx_add_inherited_sockets(ngx_cycle_t *cycle)
{u_char           *p, *v, *inherited;ngx_int_t         s;ngx_listening_t  *ls;inherited = (u_char *) getenv(NGINX_VAR);

此次 

inherited 是 null,没有需要继承的 套接字描述符

    if (inherited == NULL) {return NGX_OK;}

返回 NGX_OK


回到 main 函数中

接下来是:

    if (ngx_preinit_modules() != NGX_OK) {return 1;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_preinit_modules 函数-CSDN博客

进入 ngx_preinit_modules

ngx_int_t
ngx_preinit_modules(void)
{ngx_uint_t  i;for (i = 0; ngx_modules[i]; i++) {ngx_modules[i]->index = i;ngx_modules[i]->name = ngx_module_names[i];}ngx_modules_n = i;ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES;return NGX_OK;
}

进入循环,遍历 ngx_modules 数组

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_modules-CSDN博客

为每个模块的 index name 字段赋值

此次的情况是:

ngx_modules[0]->index = 0
ngx_modules[0]->name = ngx_core_module
ngx_modules[1]->index = 1
ngx_modules[1]->name = ngx_errlog_module
ngx_modules[2]->index = 2
ngx_modules[2]->name = ngx_conf_module
ngx_modules[3]->index = 3
ngx_modules[3]->name = ngx_openssl_module
ngx_modules[4]->index = 4
ngx_modules[4]->name = ngx_regex_module
ngx_modules[5]->index = 5
ngx_modules[5]->name = ngx_events_module
ngx_modules[6]->index = 6
ngx_modules[6]->name = ngx_event_core_module
ngx_modules[7]->index = 7
ngx_modules[7]->name = ngx_epoll_module
ngx_modules[8]->index = 8
ngx_modules[8]->name = ngx_http_module
ngx_modules[9]->index = 9
ngx_modules[9]->name = ngx_http_core_module
ngx_modules[10]->index = 10
ngx_modules[10]->name = ngx_http_log_module
ngx_modules[11]->index = 11
ngx_modules[11]->name = ngx_http_upstream_module
ngx_modules[12]->index = 12
ngx_modules[12]->name = ngx_http_v2_module
ngx_modules[13]->index = 13
ngx_modules[13]->name = ngx_http_static_module
ngx_modules[14]->index = 14
ngx_modules[14]->name = ngx_http_gzip_static_module
ngx_modules[15]->index = 15
ngx_modules[15]->name = ngx_http_autoindex_module
ngx_modules[16]->index = 16
ngx_modules[16]->name = ngx_http_index_module
ngx_modules[17]->index = 17
ngx_modules[17]->name = ngx_http_mirror_module
ngx_modules[18]->index = 18
ngx_modules[18]->name = ngx_http_try_files_module
ngx_modules[19]->index = 19
ngx_modules[19]->name = ngx_http_auth_basic_module
ngx_modules[20]->index = 20
ngx_modules[20]->name = ngx_http_access_module
ngx_modules[21]->index = 21
ngx_modules[21]->name = ngx_http_limit_conn_module
ngx_modules[22]->index = 22
ngx_modules[22]->name = ngx_http_limit_req_module
ngx_modules[23]->index = 23
ngx_modules[23]->name = ngx_http_geo_module
ngx_modules[24]->index = 24
ngx_modules[24]->name = ngx_http_map_module
ngx_modules[25]->index = 25
ngx_modules[25]->name = ngx_http_split_clients_module
ngx_modules[26]->index = 26
ngx_modules[26]->name = ngx_http_referer_module
ngx_modules[27]->index = 27
ngx_modules[27]->name = ngx_http_rewrite_module
ngx_modules[28]->index = 28
ngx_modules[28]->name = ngx_http_ssl_module
ngx_modules[29]->index = 29
ngx_modules[29]->name = ngx_http_proxy_module
ngx_modules[30]->index = 30
ngx_modules[30]->name = ngx_http_fastcgi_module
ngx_modules[31]->index = 31
ngx_modules[31]->name = ngx_http_uwsgi_module
ngx_modules[32]->index = 32
ngx_modules[32]->name = ngx_http_scgi_module
ngx_modules[33]->index = 33
ngx_modules[33]->name = ngx_http_grpc_module
ngx_modules[34]->index = 34
ngx_modules[34]->name = ngx_http_memcached_module
ngx_modules[35]->index = 35
ngx_modules[35]->name = ngx_http_empty_gif_module
ngx_modules[36]->index = 36
ngx_modules[36]->name = ngx_http_browser_module
ngx_modules[37]->index = 37
ngx_modules[37]->name = ngx_http_upstream_hash_module
ngx_modules[38]->index = 38
ngx_modules[38]->name = ngx_http_upstream_ip_hash_module
ngx_modules[39]->index = 39
ngx_modules[39]->name = ngx_http_upstream_least_conn_module
ngx_modules[40]->index = 40
ngx_modules[40]->name = ngx_http_upstream_random_module
ngx_modules[41]->index = 41
ngx_modules[41]->name = ngx_http_upstream_keepalive_module
ngx_modules[42]->index = 42
ngx_modules[42]->name = ngx_http_upstream_zone_module
ngx_modules[43]->index = 43
ngx_modules[43]->name = ngx_http_write_filter_module
ngx_modules[44]->index = 44
ngx_modules[44]->name = ngx_http_header_filter_module
ngx_modules[45]->index = 45
ngx_modules[45]->name = ngx_http_chunked_filter_module
ngx_modules[46]->index = 46
ngx_modules[46]->name = ngx_http_v2_filter_module
ngx_modules[47]->index = 47
ngx_modules[47]->name = ngx_http_range_header_filter_module
ngx_modules[48]->index = 48
ngx_modules[48]->name = ngx_http_gzip_filter_module
ngx_modules[49]->index = 49
ngx_modules[49]->name = ngx_http_postpone_filter_module
ngx_modules[50]->index = 50
ngx_modules[50]->name = ngx_http_ssi_filter_module
ngx_modules[51]->index = 51
ngx_modules[51]->name = ngx_http_charset_filter_module
ngx_modules[52]->index = 52
ngx_modules[52]->name = ngx_http_userid_filter_module
ngx_modules[53]->index = 53
ngx_modules[53]->name = ngx_http_headers_filter_module
ngx_modules[54]->index = 54
ngx_modules[54]->name = ngx_http_copy_filter_module
ngx_modules[55]->index = 55
ngx_modules[55]->name = ngx_http_range_body_filter_module
ngx_modules[56]->index = 56
ngx_modules[56]->name = ngx_http_not_modified_filter_module
ngx_modules[57]->index = 57
ngx_modules[57]->name = ngx_stream_module
ngx_modules[58]->index = 58
ngx_modules[58]->name = ngx_stream_core_module
ngx_modules[59]->index = 59
ngx_modules[59]->name = ngx_stream_log_module
ngx_modules[60]->index = 60
ngx_modules[60]->name = ngx_stream_proxy_module
ngx_modules[61]->index = 61
ngx_modules[61]->name = ngx_stream_upstream_module
ngx_modules[62]->index = 62
ngx_modules[62]->name = ngx_stream_write_filter_module
ngx_modules[63]->index = 63
ngx_modules[63]->name = ngx_stream_ssl_module
ngx_modules[64]->index = 64
ngx_modules[64]->name = ngx_stream_limit_conn_module
ngx_modules[65]->index = 65
ngx_modules[65]->name = ngx_stream_access_module
ngx_modules[66]->index = 66
ngx_modules[66]->name = ngx_stream_geo_module
ngx_modules[67]->index = 67
ngx_modules[67]->name = ngx_stream_map_module
ngx_modules[68]->index = 68
ngx_modules[68]->name = ngx_stream_split_clients_module
ngx_modules[69]->index = 69
ngx_modules[69]->name = ngx_stream_return_module
ngx_modules[70]->index = 70
ngx_modules[70]->name = ngx_stream_set_module
ngx_modules[71]->index = 71
ngx_modules[71]->name = ngx_stream_upstream_hash_module
ngx_modules[72]->index = 72
ngx_modules[72]->name = ngx_stream_upstream_least_conn_module
ngx_modules[73]->index = 73
ngx_modules[73]->name = ngx_stream_upstream_random_module
ngx_modules[74]->index = 74
ngx_modules[74]->name = ngx_stream_upstream_zone_module

ngx_modules_n 静态模块的总数

ngx_max_module 表示Nginx支持的最大模块数量

NGX_MAX_DYNAMIC_MODULES  动态加载模块的最大数量

ngx_modules_n=75
ngx_max_module(=203) = ngx_modules_n(75) + NGX_MAX_DYNAMIC_MODULES(128)  


回到 main 函数中

接下来是:

cycle = ngx_init_cycle(&init_cycle);if (cycle == NULL) {if (ngx_test_config) {ngx_log_stderr(0, "configuration file %s test failed",init_cycle.conf_file.data);}return 1;}

调用 ngx_init_cycle

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_cycle 函数-CSDN博客

进入 ngx_init_cycle

ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{void                *rv;char               **senv;ngx_uint_t           i, n;ngx_log_t           *log;ngx_time_t          *tp;ngx_conf_t           conf;ngx_pool_t          *pool;ngx_cycle_t         *cycle, **old;ngx_shm_zone_t      *shm_zone, *oshm_zone;ngx_list_part_t     *part, *opart;ngx_open_file_t     *file;ngx_listening_t     *ls, *nls;ngx_core_conf_t     *ccf, *old_ccf;ngx_core_module_t   *module;char                 hostname[NGX_MAXHOSTNAMELEN];ngx_timezone_update();/* force localtime update with a new timezone */tp = ngx_timeofday();tp->sec = 0;ngx_time_update();

更新时间

   log = old_cycle->log;

获取之前的 log 对象,暂时还是用它来记录 log

   pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);if (pool == NULL) {return NULL;}pool->log = log;

创建一个新的内存池,然后设置它使用的 log

此次的情况是:

pool = ngx_create_pool(16384, log)
pool= 0x5f33e4db67b0 (地址)

接下来是: 

   cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));if (cycle == NULL) {ngx_destroy_pool(pool);return NULL;}

此次的情况是:

cycle = ngx_pcalloc(pool, 648);
cycle= 0x5c67408e7800 

    cycle->pool = pool;cycle->log = log;cycle->old_cycle = old_cycle;
   cycle->conf_prefix.len = old_cycle->conf_prefix.len;cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);if (cycle->conf_prefix.data == NULL) {ngx_destroy_pool(pool);return NULL;}

给字段赋值

此次的情况是:

cycle->conf_prefix.len =28
cycle->conf_prefix.data=/home/wsd/桌面/nginx/conf/ 

    cycle->prefix.len = old_cycle->prefix.len;cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);if (cycle->prefix.data == NULL) {ngx_destroy_pool(pool);return NULL;}

此次的情况是:

cycle->prefix.len = 17)
cycle->prefix.data= /usr/local/nginx/

    cycle->error_log.len = old_cycle->error_log.len;cycle->error_log.data = ngx_pnalloc(pool, old_cycle->error_log.len + 1);if (cycle->error_log.data == NULL) {ngx_destroy_pool(pool);return NULL;}ngx_cpystrn(cycle->error_log.data, old_cycle->error_log.data,old_cycle->error_log.len + 1);

此次的情况是:

cycle->error_log.len=36 

cycle->error_log.data=/home/wsd/桌面/nginx/LOG/error.log 

   cycle->conf_file.len = old_cycle->conf_file.len;cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);if (cycle->conf_file.data == NULL) {ngx_destroy_pool(pool);return NULL;}ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,old_cycle->conf_file.len + 1);

此次的情况是:

cycle->conf_file.len=38
cycle->conf_file.data=/home/wsd/桌面/nginx/conf/nginx.conf

    cycle->conf_param.len = old_cycle->conf_param.len;cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);if (cycle->conf_param.data == NULL) {ngx_destroy_pool(pool);return NULL;}

此次的情况是:

cycle->conf_param.len=0
cycle->conf_param.data 是 null

运行时没有给命令行参数

    n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;

 此次的情况是:

n = 0 ? 0 : 10;
n=10

    if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *))!= NGX_OK){ngx_destroy_pool(pool);return NULL;}

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_array_init 函数-CSDN博客

    ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *));

 将 paths 数组的前 n 个元素清零

    if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))!= NGX_OK){ngx_destroy_pool(pool);return NULL;}

 初始化数组 config_dump

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_dump_t-CSDN博客

    ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel,ngx_str_rbtree_insert_value);

 Ubuntu 下 nginx-1.24.0 源码分析 - ngx_rbtree_init-CSDN博客

   if (old_cycle->open_files.part.nelts) {n = old_cycle->open_files.part.nelts;for (part = old_cycle->open_files.part.next; part; part = part->next) {n += part->nelts;}} else {n = 20;}

此次运行的情况是:

old_cycle->open_files.part.nelts=0

所以进入 else 
n=20

if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))!= NGX_OK){ngx_destroy_pool(pool);return NULL;}

初始化新周期的 open_files 列表。

此次运行的情况是:

ngx_list_init(&cycle->open_files, pool, n=20, sizeof(ngx_open_file_t)=40)

    if (old_cycle->shared_memory.part.nelts) {n = old_cycle->shared_memory.part.nelts;for (part = old_cycle->shared_memory.part.next; part; part = part->next){n += part->nelts;}} else {n = 1;}

 设置新周期的 shared_memory 的元素数量

此次运行的情况是:

old_cycle->shared_memory.part.nelts=0 

所以 进入else
n=1

  if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))!= NGX_OK){ngx_destroy_pool(pool);return NULL;}

 初始化 shared_memory

此次运行的情况是:


ngx_list_init(&cycle->shared_memory, pool, n=1, sizeof(ngx_shm_zone_t)=88 )

   n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;

 此次运行的情况是:

n(=10) = old_cycle->listening.nelts(=0) ? old_cycle->listening.nelts(=0) : 10 

  if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t))!= NGX_OK){ngx_destroy_pool(pool);return NULL;}

初始化 cycle->listening 数组

此次运行的情况是:

ngx_array_init(&cycle->listening, pool, n(=10), sizeof(ngx_listening_t)(=296))  

    ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t));

cycle->listening 内存区域清 0

   ngx_queue_init(&cycle->reusable_connections_queue);
    cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));if (cycle->conf_ctx == NULL) {ngx_destroy_pool(pool);return NULL;}

从内存池 pool 中分配一个指针数组 conf_ctx,每个元素对应一个模块的配置结构指针。 


    if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");ngx_destroy_pool(pool);return NULL;}

调用 gethostname() 系统调用获取本地主机名,存储到 hostname 缓冲区。

    hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';cycle->hostname.len = ngx_strlen(hostname);

确保 hostname 以 \0 结尾

计算主机名的实际长度(不含终止符),存储到 cycle->hostname.len 

    cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);if (cycle->hostname.data == NULL) {ngx_destroy_pool(pool);return NULL;}

从内存池 pool 分配内存,存储主机名的副本

    ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);

将主机名转换为全小写,存储到 cycle->hostname.data

此次运行的情况是:

hostname=wsd-vm 
cycle->hostname.len=6
cycle->hostname.data = ngx_pnalloc(pool, 6) 
cycle->hostname.data=0x6165d5b590d0 地址
cycle->hostname.data = wsd-vm

    if (ngx_cycle_modules(cycle) != NGX_OK) {ngx_destroy_pool(pool);return NULL;}

调用 ngx_cycle_modules 初始化 cycle->modules 数组,该数组包含所有核心模块的指针


    for (i = 0; cycle->modules[i]; i++) {if (cycle->modules[i]->type != NGX_CORE_MODULE) {continue;}

遍历所有核心模块

module = cycle->modules[i]->ctx;

获取核心模块的配置


http://www.mrgr.cn/news/93712.html

相关文章:

  • 【 <一> 炼丹初探:JavaWeb 的起源与基础】之 Servlet 过滤器:实现请求的预处理与后处理
  • VBA 列方向合并单元格,左侧范围大于右侧范围
  • WSL安装及问题
  • Nginx快速安装-Linux-CentOS7
  • 美杜莎:带多个解码头的简单LLM推理加速框架
  • UI自动化测试Selenium安装教程(1)
  • 【Linux内核系列】:深入解析输出以及输入重定向
  • selenium库
  • TI毫米波雷达开发 —— 串口输出数据解析
  • 09第三方库的使用
  • VBA 数据库同一表的当前行与其他行的主键重复判断实现方案
  • 迅投miniQMT量化交易之【网格交易】的实现(七)——__init__()方法
  • 【网络】HTTP协议、HTTPS协议
  • 【linux网络编程】套接字编程API详细介绍
  • 08动态库与静态库
  • element-plus中table组件的使用
  • 算法进阶——双指针
  • c语言笔记 数组进阶题目的理解
  • 渗透测试之利用sql拿shell(附完整流程+防御方案)【上】
  • OpenManus:开源版Manus的快速安装及使用「喂饭教程」