ngx_single_process_cycle
1 定义ngx_single_process_cycle 函数 定义在 ./nginx-1.24.0/src/os/unix/ngx_process_cycle.cvoidngx_single_process_cycle(ngx_cycle_t*cycle){ngx_uint_ti;if(ngx_set_environment(cycle,NULL)NULL){/* fatal */exit(2);}for(i0;cycle-modules[i];i){if(cycle-modules[i]-init_process){if(cycle-modules[i]-init_process(cycle)NGX_ERROR){/* fatal */exit(2);}}}for(;;){ngx_log_debug0(NGX_LOG_DEBUG_EVENT,cycle-log,0,worker cycle);ngx_process_events_and_timers(cycle);if(ngx_terminate||ngx_quit){for(i0;cycle-modules[i];i){if(cycle-modules[i]-exit_process){cycle-modules[i]-exit_process(cycle);}}ngx_master_process_exit(cycle);}if(ngx_reconfigure){ngx_reconfigure0;ngx_log_error(NGX_LOG_NOTICE,cycle-log,0,reconfiguring);cyclengx_init_cycle(cycle);if(cycleNULL){cycle(ngx_cycle_t*)ngx_cycle;continue;}ngx_cyclecycle;}if(ngx_reopen){ngx_reopen0;ngx_log_error(NGX_LOG_NOTICE,cycle-log,0,reopening logs);ngx_reopen_files(cycle,(ngx_uid_t)-1);}}}ngx_single_process_cycle 是 Nginx 在单进程模式下的主循环函数。 它完成进程运行环境初始化与各模块启动后 进入无限循环处理网络事件和定时器2 详解1 函数签名voidngx_single_process_cycle(ngx_cycle_t*cycle)返回值 返回值类型void 该函数没有返回值。参数 ngx_cycle_t *cycle Nginx 的“全局运行时上下文”2 逻辑流程1 局部变量 2 设置进程的运行环境变量 3 模块的进程初始化 4 事件循环1 局部变量{ngx_uint_ti;2 设置进程的运行环境变量if(ngx_set_environment(cycle,NULL)NULL){/* fatal */exit(2);}设置进程的运行环境变量 第二个参数 NULL 的含义 表示 这是初始设置环境变量的场景而非退出时的清理场景。3 模块的进程初始化for(i0;cycle-modules[i];i){if(cycle-modules[i]-init_process){if(cycle-modules[i]-init_process(cycle)NGX_ERROR){/* fatal */exit(2);}}}依次调用所有已加载模块的进程级初始化回调函数。 若任何一个模块的初始化失败进程将被立即终止。4 事件循环for(;;){ngx_log_debug0(NGX_LOG_DEBUG_EVENT,cycle-log,0,worker cycle);ngx_process_events_and_timers(cycle);if(ngx_terminate||ngx_quit){for(i0;cycle-modules[i];i){if(cycle-modules[i]-exit_process){cycle-modules[i]-exit_process(cycle);}}ngx_master_process_exit(cycle);}if(ngx_reconfigure){ngx_reconfigure0;ngx_log_error(NGX_LOG_NOTICE,cycle-log,0,reconfiguring);cyclengx_init_cycle(cycle);if(cycleNULL){cycle(ngx_cycle_t*)ngx_cycle;continue;}ngx_cyclecycle;}if(ngx_reopen){ngx_reopen0;ngx_log_error(NGX_LOG_NOTICE,cycle-log,0,reopening logs);ngx_reopen_files(cycle,(ngx_uid_t)-1);}}}Nginx 单进程模式的 主事件循环 它在一个无限循环中持续处理网络 I/O 事件和定时器任务 并在每次循环结束后检查由信号触发的全局标志位 执行 优雅退出、配置重载 或 日志文件重开 等管理操作#1 构建一个永不主动退出的无限循环。 服务器进程的典型结构 一旦完成初始化便进入“等待事件 → 处理事件 → 检查状态 → 继续等待”的循环 直到收到明确的退出信号。 单进程模式没有 master 进程来管理生命周期 因此所有信号响应都内嵌在这个循环中。#2 调试日志 ngx_log_debug0 是 Nginx 的调试日志宏 标记一次事件循环的开始便于开发者追踪循环执行#3 核心事件与定时器处理 调用事件驱动机制 如 epoll_wait、kqueue、select 等阻塞等待监听套接字和已连接套接字上的 I/O 事件。 分发事件 将就绪的事件交给对应的读写回调函数处理例如接受新连接、读取 HTTP 请求、发送响应数据。 处理定时器 检查红黑树中管理的定时器执行到期的超时回调如连接空闲超时、请求处理超时、延迟任务等。 维护连接池与内存池 回收已关闭的连接资源。 单进程模式下的特殊性 该函数同样会阻塞等待事件发生 但在单进程模式下没有独立的 master 进程来管理 worker 因此所有信号如 SIGHUP、SIGQUIT会直接中断该函数的阻塞等待 使得循环能够及时检查 ngx_terminate 等标志位。#4 退出处理ngx_terminate 或 ngx_quit 全局标志来源 这两个变量在信号处理函数如 ngx_signal_handler中被设置为 1。 ngx_terminate 收到 强制终止信号SIGTERM、SIGINT时置位。 ngx_quit 收到 优雅退出信号SIGQUIT时置位。 检查时机 在每次 ngx_process_events_and_timers 返回后立即检查保证对退出请求的及时响应。#4-1 调用各模块的退出清理回调#4-2 执行最终退出 该函数原为 master 进程的退出清理函数但在单进程模式下同样被复用。 它执行以下最终操作 删除 pid 文件若存在。 释放之前分配的环境变量内存。 关闭所有监听套接字。 刷新并关闭所有日志文件。 调用 exit(0) 终止进程。#5 配置重载处理ngx_reconfigure 标志来源 SIGHUP 信号处理函数会将 ngx_reconfigure 置为 1。 立即清零 防止信号处理函数在一次循环内多次触发重载逻辑或导致嵌套重载。 日志记录用 NGX_LOG_NOTICE 级别记录一条“正在重载配置”的消息。#5-1 创建新 cycle 解析配置文件生成一个新的 ngx_cycle_t 结构。 参数旧 cycle 作为蓝本 ngx_init_cycle 会尝试复用其中可以继承的资源例如已经打开的监听套接字、共享内存段 避免因重载导致服务中断。 成功返回新 cycle 的指针。 失败返回 NULL通常是因为配置文件存在语法错误或系统资源不足。#5-2 重载失败的回退机制 失败处理 若新 cycle 创建失败则 回退 到旧的 cycle 继续运行。 ngx_cycle 是全局变量始终指向当前正在使用的有效 ngx_cycle_t 对象。 将局部变量 cycle 重新指向 ngx_cycle保证后续循环依然使用旧配置。 continue 跳过后续 ngx_cycle cycle; 语句进入下一轮事件循环。#5-3 更新全局 cycle ngx_cycle cycle; 成功重载将全局指针 ngx_cycle 更新为新 cycle。#6 日志文件重开处理 标志来源SIGUSR1 信号处理函数将 ngx_reopen 置为 1。 作用重新打开所有 Nginx 管理的日志文件如 access.log、error.log。 ngx_reopen_files 参数说明 cycle当前配置上下文包含了需要重开的文件列表。 (ngx_uid_t) -1特殊值表示 不改变日志文件的所属用户。