ngx_signal_process

张开发
2026/4/19 17:45:32 15 分钟阅读

分享文章

ngx_signal_process
1 定义ngx_signal_process 函数 定义在 ./nginx-1.24.0/src/core/ngx_cycle.cngx_int_tngx_signal_process(ngx_cycle_t*cycle,char*sig){ssize_tn;ngx_pid_tpid;ngx_file_tfile;ngx_core_conf_t*ccf;u_char buf[NGX_INT64_LEN2];ngx_log_error(NGX_LOG_NOTICE,cycle-log,0,signal process started);ccf(ngx_core_conf_t*)ngx_get_conf(cycle-conf_ctx,ngx_core_module);ngx_memzero(file,sizeof(ngx_file_t));file.nameccf-pid;file.logcycle-log;file.fdngx_open_file(file.name.data,NGX_FILE_RDONLY,NGX_FILE_OPEN,NGX_FILE_DEFAULT_ACCESS);if(file.fdNGX_INVALID_FILE){ngx_log_error(NGX_LOG_ERR,cycle-log,ngx_errno,ngx_open_file_n \%s\ failed,file.name.data);return1;}nngx_read_file(file,buf,NGX_INT64_LEN2,0);if(ngx_close_file(file.fd)NGX_FILE_ERROR){ngx_log_error(NGX_LOG_ALERT,cycle-log,ngx_errno,ngx_close_file_n \%s\ failed,file.name.data);}if(nNGX_ERROR){return1;}while(n--(buf[n]CR||buf[n]LF)){/* void */}pidngx_atoi(buf,n);if(pid(ngx_pid_t)NGX_ERROR){ngx_log_error(NGX_LOG_ERR,cycle-log,0,invalid PID number \%*s\ in \%s\,n,buf,file.name.data);return1;}returnngx_os_signal_process(cycle,sig,pid);}ngx_signal_process 函数的作用是 从 Nginx 配置指定的 PID 文件中读取主进程号 并向该进程发送指定的信号如 reload、stop、quit 等 从而实现 Nginx 的优雅重启、停止、日志重开等运行中管理操作。2 详解1 函数签名ngx_int_tngx_signal_process(ngx_cycle_t*cycle,char*sig)返回值 成功返回 NGX_OK定义为 0。 失败返回 NGX_ERROR定义为 -1参数 ngx_cycle_t *cycle 指向当前运行周期环境 参数 char *sig C 风格字符串指针指向以 \0 结尾的字符数组 实际传入内容 Nginx 定义的信号名称字符串例如 stop —— 对应快速关闭SIGTERM。 quit —— 对应优雅关闭SIGQUIT。 reload —— 对应重新加载配置文件SIGHUP。 reopen —— 对应重新打开日志文件SIGUSR1。2 逻辑流程1 局部变量 2 记录日志 3 读取 PID 文件内容 4 解析读取内容 5 发送信号1 局部变量{ssize_tn;ngx_pid_tpid;ngx_file_tfile;ngx_core_conf_t*ccf;u_char buf[NGX_INT64_LEN2];2 记录日志ngx_log_error(NGX_LOG_NOTICE,cycle-log,0,signal process started);3 读取 PID 文件内容ccf(ngx_core_conf_t*)ngx_get_conf(cycle-conf_ctx,ngx_core_module);获取核心模块配置ngx_memzero(file,sizeof(ngx_file_t));初始化文件结构体 将栈上的 ngx_file_t 结构体变量 file 的所有字节清零。file.nameccf-pid;file.logcycle-log;将核心配置中的 PID 文件路径赋值给 file.name 将全局日志对象 cycle-log 赋给 file.logfile.fdngx_open_file(file.name.data,NGX_FILE_RDONLY,NGX_FILE_OPEN,NGX_FILE_DEFAULT_ACCESS);if(file.fdNGX_INVALID_FILE){ngx_log_error(NGX_LOG_ERR,cycle-log,ngx_errno,ngx_open_file_n \%s\ failed,file.name.data);return1;}#1 尝试以只读模式打开 PID 文件并返回文件描述符 参数 1 file.name.data文件路径字符串。 参数 2 NGX_FILE_RDONLY只读模式通常是 O_RDONLY。 参数 3 NGX_FILE_OPEN表示只打开已存在的文件不创建 参数 4 NGX_FILE_DEFAULT_ACCESS 默认权限模式创建文件时用但此处未创建所以实际上被忽略或为 0。 返回值是文件描述符 如果失败则返回 NGX_INVALID_FILE通常是 -1。 意义 PID 文件必须已经存在由正在运行的 Nginx 主进程创建 这里使用只读且不创建的模式打开如果文件不存在直接失败符合预期。 #2 如果打开文件失败记录错误日志并返回错误码 1nngx_read_file(file,buf,NGX_INT64_LEN2,0);读取 PID 文件内容到缓冲区 从已打开的文件中读取数据到 buf并返回实际读取的字节数。 参数 1 file包含文件描述符和日志对象的文件结构。 参数 2 buf目标缓冲区大小为 NGX_INT64_LEN 2 字节。 参数 3 NGX_INT64_LEN 2读取的最大字节数。2 是为了可能的回车换行符 \r\n。 参数 4 0偏移量表示从文件当前位置文件开头开始读取。 返回值 n成功读取的字节数若出错则返回 NGX_ERROR。 意义 只读取有限字节因为 PID 文件通常只有一个短数字和换行符不需要读取整个文件。 使用固定大小的栈缓冲区避免动态内存分配。if(ngx_close_file(file.fd)NGX_FILE_ERROR){ngx_log_error(NGX_LOG_ALERT,cycle-log,ngx_errno,ngx_close_file_n \%s\ failed,file.name.data);}关闭文件if(nNGX_ERROR){return1;}若 读取操作出现错误 返回失败码 14 解析读取内容while(n--(buf[n]CR||buf[n]LF)){/* void */}pidngx_atoi(buf,n);if(pid(ngx_pid_t)NGX_ERROR){ngx_log_error(NGX_LOG_ERR,cycle-log,0,invalid PID number \%*s\ in \%s\,n,buf,file.name.data);return1;}#1 去除缓冲区尾部的换行符CR 或 LF 将 n当前表示有效读取的字节总数逐步减小 跳过末尾所有的回车符CR\r和换行符LF\n。 循环结束后n 恰好指向最后一个有效数字的索引而非长度 #2 将修剪后的字符串转换为整数 PID n 是前置递增将上一步得到的“末位索引”加 1还原为有效字符串的实际长度。 #3 转换失败的错误处理5 发送信号returnngx_os_signal_process(cycle,sig,pid);}完成 实际的、由操作系统执行的信号发送动作 并直接将执行结果作为退出码向上返回

更多文章