新闻详情

新闻详情

首页 / 资讯中心 / 详情

ngx_signal_worker_processes

发布时间:2026/9/3 1:09:52来源:尧图网络
ngx_signal_worker_processes
1 定义ngx_signal_worker_processes 函数 定义在 ./nginx-1.24.0/src/os/unix/ngx_process_cycle.cstaticvoidngx_signal_worker_processes(ngx_cycle_t*cycle,intsigno){ngx_int_ti;ngx_err_terr;ngx_channel_tch;ngx_memzero(ch,sizeof(ngx_channel_t));#if(NGX_BROKEN_SCM_RIGHTS)ch.command0;#elseswitch(signo){casengx_signal_value(NGX_SHUTDOWN_SIGNAL):ch.commandNGX_CMD_QUIT;break;casengx_signal_value(NGX_TERMINATE_SIGNAL):ch.commandNGX_CMD_TERMINATE;break;casengx_signal_value(NGX_REOPEN_SIGNAL):ch.commandNGX_CMD_REOPEN;break;default:ch.command0;}#endifch.fd-1;for(i0;ingx_last_process;i){ngx_log_debug7(NGX_LOG_DEBUG_EVENT,cycle-log,0,child: %i %P e:%d t:%d d:%d r:%d j:%d,i,ngx_processes[i].pid,ngx_processes[i].exiting,ngx_processes[i].exited,ngx_processes[i].detached,ngx_processes[i].respawn,ngx_processes[i].just_spawn);if(ngx_processes[i].detached||ngx_processes[i].pid-1){continue;}if(ngx_processes[i].just_spawn){ngx_processes[i].just_spawn0;continue;}if(ngx_processes[i].exitingsignongx_signal_value(NGX_SHUTDOWN_SIGNAL)){continue;}if(ch.command){if(ngx_write_channel(ngx_processes[i].channel[0],ch,sizeof(ngx_channel_t),cycle-log)NGX_OK){if(signo!ngx_signal_value(NGX_REOPEN_SIGNAL)){ngx_processes[i].exiting1;}continue;}}ngx_log_debug2(NGX_LOG_DEBUG_CORE,cycle-log,0,kill (%P, %d),ngx_processes[i].pid,signo);if(kill(ngx_processes[i].pid,signo)-1){errngx_errno;ngx_log_error(NGX_LOG_ALERT,cycle-log,err,kill(%P, %d) failed,ngx_processes[i].pid,signo);if(errNGX_ESRCH){ngx_processes[i].exited1;ngx_processes[i].exiting0;ngx_reap1;}continue;}if(signo!ngx_signal_value(NGX_REOPEN_SIGNAL)){ngx_processes[i].exiting1;}}}ngx_signal_worker_processes 函数是 Nginx 主进程中用于向所有工作进程及辅助进程分发信号的函数。 它优先通过进程间通道发送优雅的控制命令如退出、重新打开日志 在通道不可用或失败时则使用 kill 系统调用直接发送信号 并根据发送结果更新进程的退出状态。2 详解1 函数签名staticvoidngx_signal_worker_processes(ngx_cycle_t*cycle,intsigno)返回值 函数不返回任何值参数1 ngx_cycle_t *cycle 当前运行周期上下文环境参数2 int signo 表示要发送的信号编号2 逻辑流程1 命令准备 1 不支持传递文件描述符命令置为 0表示没有有效命令 2 支持传递文件描述符根据输入信号设置对应的命令 2 遍历所有进程发送命令 1 跳过无需发送命令的进程 2 命令有效通过通道发送命令 3 命令无效或通道发送命令失败通过 kill 发送信号1 命令准备{ngx_int_ti;ngx_err_terr;ngx_channel_tch;局部变量声明ngx_memzero(ch,sizeof(ngx_channel_t));将 ch 结构体所有字段清零若系统不支持通过通道传递文件描述符 定义了 NGX_BROKEN_SCM_RIGHTS 则编译以下代码块。#if(NGX_BROKEN_SCM_RIGHTS)ch.command0;直接将通道命令置为 0表示没有有效命令。 逻辑 既然系统不支持通道传递描述符 那么通道命令机制也不可用 因此强制命令为 0后续将跳过通道发送只使用 kill 信号。支持传递文件描述符#elseswitch(signo){casengx_signal_value(NGX_SHUTDOWN_SIGNAL):ch.commandNGX_CMD_QUIT;break;casengx_signal_value(NGX_TERMINATE_SIGNAL):ch.commandNGX_CMD_TERMINATE;break;casengx_signal_value(NGX_REOPEN_SIGNAL):ch.commandNGX_CMD_REOPEN;break;default:ch.command0;}#endif根据输入信号选择对应的通道命令优雅关闭信号通常为 SIGQUIT 通道命令设为 NGX_CMD_QUIT 工作进程收到后会优雅关闭。强制终止信号通常为 SIGINT 或 SIGTERM 通道命令设为 NGX_CMD_TERMINATE 工作进程收到后快速退出。重新打开日志文件信号通常为 SIGUSR1 通道命令设为 NGX_CMD_REOPEN 工作进程收到后重新打开日志文件。其他信号 不设置命令0 表示无效 因为其他信号不需要通过通道传递特殊语义。ch.fd-1;将通道消息中的文件描述符字段设为 -1无效值。 本次通知不传递任何文件描述符显式标记为无效接收方应忽略该字段。2 遍历所有进程发送命令for(i0;ingx_last_process;i){遍历全局进程数组 ngx_processes。 ngx_last_process 是当前管理的进程总数。 对每一个记录在案的进程尝试发送信号。ngx_log_debug7(NGX_LOG_DEBUG_EVENT,cycle-log,0,child: %i %P e:%d t:%d d:%d r:%d j:%d,i,ngx_processes[i].pid,ngx_processes[i].exiting,ngx_processes[i].exited,ngx_processes[i].detached,ngx_processes[i].respawn,ngx_processes[i].just_spawn);输出当前进程的详细状态到调试日志if(ngx_processes[i].detached||ngx_processes[i].pid-1){continue;}过滤已分离或 PID 无效的进程。 分离的进程已脱离主进程管理 PID 为 -1 表示进程不存在。 这两种情况均无需也无法发送信号直接跳过。 避免向无效目标发送信号if(ngx_processes[i].just_spawn){ngx_processes[i].just_spawn0;continue;}跳过刚刚生成fork的进程并清除该标志。 刚 fork 出的进程可能还未完成信号处理函数的设置 立即发送信号可能造成竞态或未定义行为。 跳过一次下次调用本函数时标志已清除可以正常发送。if(ngx_processes[i].exitingsignongx_signal_value(NGX_SHUTDOWN_SIGNAL)){continue;}避免对已经在优雅关闭的进程重复发送 SIGQUIT。 如果进程已标记为 exiting说明已收到退出指令且本次信号仍是优雅关闭则无需再次通知。 但若本次是强制终止等信号则仍会穿透此检查继续处理因为可能需要强制结束卡住的进程。 意义减少不必要的信号发送同时允许强制信号覆盖正在优雅退出的进程。if(ch.command){if(ngx_write_channel(ngx_processes[i].channel[0],ch,sizeof(ngx_channel_t),cycle-log)NGX_OK){if(signo!ngx_signal_value(NGX_REOPEN_SIGNAL)){ngx_processes[i].exiting1;}continue;}}检查通道命令是否有效非零。 如果有效优先尝试通过进程间通道发送命令 这比直接 kill 更优雅。调用 ngx_write_channel 将封装好的命令消息通过 socket 发送给目标进程。 参数 ngx_processes[i].channel[0] 是主进程端与该进程通信的 socket 文件描述符 ch 为消息内容 cycle-log 用于记录错误。 返回值成功返回 NGX_OK。若通道发送成功且信号不是重新打开日志NGX_REOPEN_SIGNAL 则将进程状态标记为 exiting 1正在退出。 然后 continue 跳过 kill 操作处理下一个进程。 重新打开日志并不导致进程退出因此不设 exiting 标志。 其他信号关闭、终止都会令进程最终退出设置标志以跟踪其退出状态。 意义精确维护进程生命周期状态为后续回收子进程提供依据。ngx_log_debug2(NGX_LOG_DEBUG_CORE,cycle-log,0,kill (%P, %d),ngx_processes[i].pid,signo);记录即将对该 PID 使用 kill 发送信号的调试日志。 当通道命令不可用或发送失败时会走到这里使用传统信号方式if(kill(ngx_processes[i].pid,signo)-1){errngx_errno;ngx_log_error(NGX_LOG_ALERT,cycle-log,err,kill(%P, %d) failed,ngx_processes[i].pid,signo);if(errNGX_ESRCH){ngx_processes[i].exited1;ngx_processes[i].exiting0;ngx_reap1;}continue;}调用 kill 系统调用向目标进程发送信号。 直接发送原始信号值 signo。 成功返回 0失败返回 -1 并设置 errno。 意义作为通道不可用或失败时的后备方案保证信号最终能被传递。若 kill 失败保存错误码并记录 ALERT 级别日志包含 PID 和信号编号。如果错误原因是 ESRCH进程不存在 则更新进程状态为已退出 (exited 1) 清除 exiting 标志并设置全局 ngx_reap 1通知主事件循环进行回收。 逻辑进程已意外终止主进程需要尽快获知并清理子进程资源。 意义自动处理子进程异常退出避免僵尸进程保证进程表状态准确。kill 失败后跳过后续状态设置因为进程未收到信号 继续处理下一个进程。if(signo!ngx_signal_value(NGX_REOPEN_SIGNAL)){ngx_processes[i].exiting1;}}}如果 kill 发送成功且信号不是重新打开日志 则同样将进程标记为 exiting 1。 与通道发送成功时的状态更新逻辑完全一致保持行为统一。 意义无论通过哪种方式发送退出信号都能正确记录进程即将退出的状态。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

MapChangeListener 源码深度解析:键值对变化的精准观察者 2026/9/3 1:07:09

MapChangeListener 源码深度解析:键值对变化的精准观察者

在深入剖析了 ListChangeListener 之后,我们迎来了 JavaFX 集合框架中的另一位重要成员:MapChangeListener<K, V>。它是 ObservableMap 的专属监听器,负责精确报告 Map 中每一次键值对的插入、更新和删除操作。 MapChangeListener 的设计与 ListChangeListener 有着本…

阅读更多 →
聊聊Java开发里那些容易被忽视的并发问题 2026/9/3 1:07:09

聊聊Java开发里那些容易被忽视的并发问题

一个看似人畜无害的HashMap&#xff0c;在并发环境下膨胀时&#xff0c;可能把两个线程的指针同时指向同一个链表头&#xff0c;然后各自写回&#xff0c;导致其中一个线程的插入悄然丢失。更隐蔽的是&#xff0c;当它触发resize时&#xff0c;旧数组到新数组的迁移过程可能让链…

阅读更多 →
Java开发中的代码重构技巧:从可读性到可维护性 2026/9/3 1:07:09

Java开发中的代码重构技巧:从可读性到可维护性

代码重构不是一次轰轰烈烈的“返工”&#xff0c;而是日复一日与代码腐坏气味的对抗。当你打开一个Service类&#xff0c;发现它的方法长度堪比一篇散文&#xff0c;CtrlC/CtrlV的痕迹比考古层还清晰&#xff0c;一个if-else嵌套能逼得调试器告老还乡——这时候&#xff0c;重构…

阅读更多 →
开题报告模板全解析:从研究背景到技术路线写作指南 2026/9/3 1:07:09

开题报告模板全解析:从研究背景到技术路线写作指南

写开题报告最怕的不是没内容&#xff0c;而是不知道导师要什么、不知道章节之间怎么衔接。这次分享一套可以直接套用的开题报告写作模板&#xff0c;覆盖选题背景、研究现状、研究内容、技术路线、创新点和进度安排&#xff0c;拿到手里改一改就能交付。对于正在做毕业论文开题…

阅读更多 →
Python批量处理图片:重命名、压缩与归档完整方案 2026/9/3 1:07:09

Python批量处理图片:重命名、压缩与归档完整方案

看到你正在整理“暗影花仙精灵王”系列的卡牌图片&#xff0c;这种图片素材通常数量多、文件名混乱、格式不统一&#xff0c;手动一张张重命名和压缩非常低效。结合我过去的批量图片处理经验&#xff0c;整理了一套完整的 Python 批量处理方案&#xff0c;可以把图片整理这件事…

阅读更多 →
Python可以写Python编译器吗 2026/9/3 1:04:09

Python可以写Python编译器吗

好的, 我此刻非得回应发问之人的问题, 即: “能够去撰写编译器这项内容吗? ”最先, 我得去确认询问者所提问题的核心理念究竟是什么。询问者想要搞清楚可不可以运用一些语言来打造出一个能够对代码实施编译操作的编译器。紧接着, 我要思索几个层面: 首先, 什么才算是编译器呢?…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞