定义在 src\os\unix\ngx_posix_init.c
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;}
#endifif (ngx_init_setproctitle(log) != NGX_OK) {return NGX_ERROR;}ngx_pagesize = getpagesize();ngx_cacheline_size = NGX_CPU_CACHE_LINE;for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }#if (NGX_HAVE_SC_NPROCESSORS_ONLN)if (ngx_ncpu == 0) {ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);}
#endifif (ngx_ncpu < 1) {ngx_ncpu = 1;}#if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);if (size > 0) {ngx_cacheline_size = size;}
#endifngx_cpuinfo();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;#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)ngx_inherited_nonblocking = 1;
#elsengx_inherited_nonblocking = 0;
#endiftp = ngx_timeofday();srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);return NGX_OK;
}
初始化操作系统相关的参数和配置,为 Nginx 的运行环境做好准备
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
NGX_HAVE_LEVEL1_DCACHE_LINESIZE=1
#if (NGX_HAVE_OS_SPECIFIC_INIT)if (ngx_os_specific_init(log) != NGX_OK) {return NGX_ERROR;}
#endif
NGX_HAVE_OS_SPECIFIC_INIT=1
ngx_os_specific_init
:调用特定于操作系统的初始化函数。
如果初始化失败,直接返回
NGX_ERROR
。
ngx_os_specific_init -CSDN博客
if (ngx_init_setproctitle(log) != NGX_OK) {return NGX_ERROR;}
ngx_init_setproctitle
:初始化进程标题设置功能,允许修改进程的命令行标题(如ps
命令中显示的内容)方便管理员通过工具查看 Nginx 进程的状态(如主进程、工作进程等)
ngx_init_setproctitle
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_setproctitle函数-CSDN博客
ngx_pagesize = getpagesize();ngx_cacheline_size = NGX_CPU_CACHE_LINE;
getpagesize()
:获取系统页面大小(单位为字节),例如 4KBgetpagesize -CSDN博客
ngx_pagesize
:全局变量,存储页面大小
ngx_cacheline_size
:全局变量,存储 CPU 缓存行大小,默认值为NGX_CPU_CACHE_LINE
NGX_CPU_CACHE_LINE
定义在 objs/ngx_auto_config.h
#ifndef NGX_CPU_CACHE_LINE #define NGX_CPU_CACHE_LINE 64 #endif
此时
ngx_pagesize=4096
ngx_cacheline_size=64
for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
for
循环 :计算页面大小的对数(ngx_pagesize_shift
),即页面大小是 2 的多少次幂。例如,4KB 的页面大小对应ngx_pagesize_shift = 12
。
此时
ngx_pagesize_shift=12
#if (NGX_HAVE_SC_NPROCESSORS_ONLN)if (ngx_ncpu == 0) {ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);}
#endif
NGX_HAVE_SC_NPROCESSORS_ONLN=1
获取当前系统在线的 CPU 核心数
ngx_ncpu == 0
ngx_ncpu 未设置
sysconf(_SC_NPROCESSORS_ONLN) :获取当前系统在线的 CPU 核心数。
sysconf-CSDN博客
ngx_ncpu :全局变量,存储 CPU 核心数。
此时
ngx_ncpu=0
进入 if 条件
调用 sysconf 后
ngx_ncpu=2
if (ngx_ncpu < 1) {ngx_ncpu = 1;}
默认值处理 :如果核心数小于 1,则设置为 1(防止异常情况)
此时条件不成立
#if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);if (size > 0) {ngx_cacheline_size = size;}
#endif
NGX_HAVE_LEVEL1_DCACHE_LINESIZE=1
sysconf(_SC_LEVEL1_DCACHE_LINESIZE)
:获取一级缓存行大小。- 更新
ngx_cacheline_size
:如果获取到的值有效,则更新全局变量。- 意图 :缓存行大小影响内存对齐和性能优化,动态获取可以适配不同的硬件架构。
此时
size=64
ngx_cacheline_size=64
ngx_cpuinfo();
ngx_cpuinfo
:获取 CPU 的详细信息(如型号、特性等),并存储在全局变量中
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;
获取文件描述符数量的限制
getrlimit :获取当前进程的最大文件描述符限制。
rlmt :存储限制值的结构体。
ngx_max_sockets :全局变量,存储最大文件描述符数量。
错误处理 :如果获取失败,记录错误日志并返回 NGX_ERROR。
意图 :文件描述符限制决定了 Nginx 能同时处理的最大连接数,合理设置可以避免资源耗尽。
getrlimit
getrlimit-CSDN博客
此时
ngx_max_sockets=1024
#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)ngx_inherited_nonblocking = 1;
#elsengx_inherited_nonblocking = 0;
#endif
NGX_HAVE_INHERITED_NONBLOCK=0
NGX_HAVE_ACCEPT4=1
ngx_inherited_nonblocking :全局变量,指示是否支持继承非阻塞套接字。
条件编译 :根据是否支持 NGX_HAVE_INHERITED_NONBLOCK 或 NGX_HAVE_ACCEPT4 设置标志。
意图 :非阻塞套接字是高并发网络编程的基础,确保套接字行为一致。
NGX_HAVE_INHERITED_NONBLOCK
含义 :表示当前系统是否支持继承非阻塞套接字(Inherited Non-blocking Sockets)。
如果定义了该宏,则表示系统允许父进程创建的套接字在子进程中保持非阻塞状态。
背景 :在传统的网络编程中,套接字的阻塞或非阻塞状态是由每个进程独立管理的。
如果系统支持继承非阻塞套接字,则父进程设置的非阻塞状态可以直接被子进程继承,而无需额外的系统调用。
优点 :减少了系统调用的开销,提高了性能。
简化了多进程模型中的套接字管理逻辑。
NGX_HAVE_ACCEPT4
含义 :表示当前系统是否支持 accept4 系统调用。
accept4 是 Linux 内核 2.6.28 引入的一个扩展版本的 accept 系统调用,允许在接收新连接时直接设置套接字选项(如非阻塞模式)。
背景 :传统的 accept 系统调用仅返回一个新的套接字文件描述符,但无法直接设置套接字选项。
使用 accept4 可以在接收连接的同时设置套接字为非阻塞模式或其他选项,从而减少额外的系统调用。
优点 :提高了性能,减少了系统调用次数。
简化了代码逻辑,避免了在 accept 后手动调用 fcntl 或其他函数来设置套接字选项。
tp = ngx_timeofday();srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
ngx_timeofday
:获取当前时间戳。srandom
:设置随机数种子。- 种子生成公式 :
(进程 ID << 16) ^ 当前秒数 ^ 当前毫秒数
。- 意图 :随机数种子用于生成唯一的随机数序列,避免每次运行时生成相同的随机数。
ngx_timeofday-CSDN博客
return NGX_OK;
返回 NGX_OK,代表成功