Nginx Master 进程直接调用 kill() 向各 Worker 发送信号,不转发、不代理、无中间通道;Worker 收到后自行处理,不反馈,Master 通过 waitpid() 检测退出。

Master 进程不“分发”信号给 Worker,而是统一发出信号——所有 Worker 收到的信号都来自 Master 的主动调用,不是转发、不是代理、也不经过中间通道。
信号由 Master 直接投递,不经过中转
当执行 nginx -s reload 或 kill -HUP $master_pid 时,操作系统先把信号(如 SIGHUP)送给 Master。Master 在自己的事件循环中捕获后,立即调用 kill() 系统调用,向每个已知的 Worker PID(或整个进程组)逐个发送对应信号(如 SIGQUIT、SIGTERM)。这不是广播,也不是消息队列,就是标准 Unix 的 kill(pid, sig) 调用。
- Master 维护着一个
ngx_processes数组,记录所有 Worker 的 PID、状态和 slot 编号 - 发送信号前,Master 会过滤掉已退出或异常的 Worker,只对活跃进程操作
- 不依赖共享内存、socket 或管道,纯靠内核进程间通信机制保证送达
Worker 不响应、不确认、不反馈
每个 Worker 启动时已注册好信号处理函数(在 ngx_signal_handler 中),收到信号后直接修改内部标志(如 ngx_quit = 1),并在下一次事件循环间隙检查并执行动作——比如关闭监听套接字、拒绝新连接、等待现有请求结束。
- 没有返回值,不向 Master 回传“已收到”或“已完成”
- Master 判断 Worker 是否退出,靠的是
waitpid()捕获子进程终止事件,而非 Worker 主动上报 - 这种“发即不管”的设计消除了双向依赖,也避免了通信失败导致控制失效
常用信号与对应动作由 Master 统一调度
Master 根据用户指令决定发什么信号、发给谁、何时发:
- SIGHUP:触发 reload 流程 → Master fork 新 Worker,再向旧 Worker 发 SIGQUIT
- SIGTERM:要求 Worker 立即停止 accept,处理完当前请求后退出
- SIGUSR1:通知所有 Worker 重新打开日志文件(配合 logrotate)
- SIGUSR2 + SIGWINCH:协同完成二进制热升级,新旧 Master/Worker 交替接管
没有“内部电话系统”,只有内核级信号投递
虽然部分源码中出现 ngx_channel_t 和 NGX_CMD_* 定义,但那仅用于极少数场景(如启动时传递 socket 句柄),**不用于常规控制信号的下发**。日常运维中的 reload、stop、reopen 全部走标准 signal 机制,和 kill -9 原理一致,只是语义更规范。
这正是 Nginx 多进程模型轻量、可靠、符合 Unix 哲学的关键:不造轮子,只用内核保障的原语。


















