定義在 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,代表成功
?