详解(5)
初始化打开文件列表(open_files
)
if (old_cycle->open_files.part.nelts) {n = old_cycle->open_files.part.nelts;for (part = old_cycle->open_files.part.next; part; part = part->next) {n += part->nelts;}} else {n = 20;}if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))!= NGX_OK){ngx_destroy_pool(pool);return NULL;}
1. 检查旧周期文件列表是否非空
if (old_cycle->open_files.part.nelts) {
ngx_list_t
判断旧cycle(old_cycle
)的open_files
链表的第一个节点(part
)是否有元素
open_files
是ngx_list_t
类型,内部由多个ngx_list_part_t
节点组成,每个节点包含多个元素。
open_files
存储 Nginx 运行时需持久打开的文件(如日志文件、共享内存文件)。在平滑重启或重新配置时,新周期需继承这些文件以避免频繁打开/关闭。
资源复用:继承旧文件描述符,减少系统调用开销,提升性能。
平滑过渡:确保新旧周期切换时文件操作不中断。
如果旧cycle的open_files
存在元素,进入计算总元素数的逻辑。
2 初始化容量 n
为旧周期文件数量
n = old_cycle->open_files.part.nelts;
获取旧周期 open_files
列表第一个分片(part
)的元素数量。
ngx_list_t
是分片链表结构,每个分片(part
)包含 nelts
个元素。
此处初始化 n
为第一个分片的元素数。
为新周期预分配足够容量,避免频繁扩容。
3 遍历所有分片累加元素数量
for (part = old_cycle->open_files.part.next; part; part = part->next) {n += part->nelts;
}
遍历旧周期 open_files
的所有分片,累加总元素数到 n
。
ngx_list_t
可能包含多个分片(如元素数量超过单个分片容量),需遍历所有分片统计总数。
精确预分配:确保新周期的 open_files
容量足够容纳所有旧文件,避免扩容开销。
4 若无旧文件,设置默认容量
} else {n = 20;
}
若旧周期无文件,设置初始容量 n = 20
。
20 是经验值,平衡内存占用与性能(避免频繁扩容)。
5 初始化 open_files
列表
if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t)) != NGX_OK)
ngx_list_init
初始化新周期的 open_files
列表。
pool
:内存池,用于管理列表内存。n
:初始容量(继承旧文件数或默认 20)。sizeof(ngx_open_file_t)
:每个元素的大小(文件描述符结构)。
6 错误处理
{ngx_destroy_pool(pool);return NULL;
}
若初始化失败,销毁内存池并终止函数。
确保失败时释放所有已分配资源