news 2026/4/21 13:28:10

ngx_get_connection

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ngx_get_connection

1 定义

ngx_get_connection 函数 定义在 ./nginx-1.24.0/src/core/ngx_connection.c
ngx_connection_t*ngx_get_connection(ngx_socket_ts,ngx_log_t*log){ngx_uint_tinstance;ngx_event_t*rev,*wev;ngx_connection_t*c;/* disable warning: Win32 SOCKET is u_int while UNIX socket is int */if(ngx_cycle->files&&(ngx_uint_t)s>=ngx_cycle->files_n){ngx_log_error(NGX_LOG_ALERT,log,0,"the new socket has number %d, ""but only %ui files are available",s,ngx_cycle->files_n);returnNULL;}ngx_drain_connections((ngx_cycle_t*)ngx_cycle);c=ngx_cycle->free_connections;if(c==NULL){ngx_log_error(NGX_LOG_ALERT,log,0,"%ui worker_connections are not enough",ngx_cycle->connection_n);returnNULL;}ngx_cycle->free_connections=c->data;ngx_cycle->free_connection_n--;if(ngx_cycle->files&&ngx_cycle->files[s]==NULL){ngx_cycle->files[s]=c;}rev=c->read;wev=c->write;ngx_memzero(c,sizeof(ngx_connection_t));c->read=rev;c->write=wev;c->fd=s;c->log=log;instance=rev->instance;ngx_memzero(rev,sizeof(ngx_event_t));ngx_memzero(wev,sizeof(ngx_event_t));rev->instance=!instance;wev->instance=!instance;rev->index=NGX_INVALID_INDEX;wev->index=NGX_INVALID_INDEX;rev->data=c;wev->data=c;wev->write=1;returnc;}
ngx_get_connection 函数的主要作用是: 从预分配的“连接池”中获取一个空闲的 ngx_connection_t 对象, 并将其与新创建的 Socket 描述符(s)进行绑定和初始化。

2 详解

1 函数签名

ngx_connection_t*ngx_get_connection(ngx_socket_ts,ngx_log_t*log)
返回值 成功返回一个指向已初始化连接结构的指针 失败返回 NULL。
参数1 ngx_socket_t s 套接字描述符 s 连接将与这个描述符绑定, 处理这个描述符收到的信息 参数2 ngx_log_t *log 日志对象 log

2 逻辑流程

1 局部变量 2 套接字描述符范围检查 3 尝试释放可重用的连接 4 获取连接 5 将连接记录到 files 数组中 6 初始化连接 7 返回连接指针

1 局部变量
{ngx_uint_tinstance;ngx_event_t*rev,*wev;ngx_connection_t*c;
instance: 用于保存旧读事件中的 instance 标志, 随后会翻转值并赋给新事件的 instance, 以解决“过期事件”问题 rev, wev: 临时指针,分别指向连接结构中原有的读事件和写事件对象。 c:最终返回的连接结构指针。

2 套接字描述符范围检查
/* disable warning: Win32 SOCKET is u_int while UNIX socket is int */if(ngx_cycle->files&&(ngx_uint_t)s>=ngx_cycle->files_n){ngx_log_error(NGX_LOG_ALERT,log,0,"the new socket has number %d, ""but only %ui files are available",s,ngx_cycle->files_n);returnNULL;}
检查给定的套接字描述符 s 是否超过了 Nginx 配置中允许的最大文件描述符数 files_n。 ngx_cycle->files 是一个指针数组, 长度由 files_n 决定, 用于快速通过文件描述符找到对应的连接结构(类似文件描述符表)。 如果套接字号超出数组大小, 后续操作 ngx_cycle->files[s] 将导致数组越界, 因此必须在此拦截并报错返回。 Nginx 使用 files 数组实现 O(1) 的 fd → connection 映射。 数组大小为 files_n,若 s 越界则无法安全存储,直接告警并返回 NULL

3 尝试释放可重用的连接
ngx_drain_connections((ngx_cycle_t*)ngx_cycle);
调用 ngx_drain_connections 尝试释放那些处于可重用状态(如 reusable 标志已设置)的空闲连接, 以应对连接池即将耗尽的情况

4 获取连接
c=ngx_cycle->free_connections;if(c==NULL){ngx_log_error(NGX_LOG_ALERT,log,0,"%ui worker_connections are not enough",ngx_cycle->connection_n);returnNULL;}
从全局空闲连接链表头部取出一个连接对象

ngx_cycle->free_connections=c->data;ngx_cycle->free_connection_n--;
更新空闲链表指针与计数 将链表头指针后移到下一个空闲连接,并将空闲连接计数减一。 c->data 在连接空闲时存放着下一个空闲连接的地址。

5 将连接记录到 files 数组中
if(ngx_cycle->files&&ngx_cycle->files[s]==NULL){ngx_cycle->files[s]=c;}
将连接记录到 files 数组中 如果 files 数组存在且对应位置尚未被占用, 就将当前连接指针存入 ngx_cycle->files[s] 建立 fd → connection 的直查映射

6 初始化连接
rev=c->read;wev=c->write;ngx_memzero(c,sizeof(ngx_connection_t));c->read=rev;c->write=wev;c->fd=s;c->log=log;
将刚获取的连接结构体所有字段清零,消除上一次使用残留的数据。 将之前保存的事件指针重新挂回连接结构。 设置文件描述符 fd 和日志对象 log。 意义:连接结构体需要完全重置, 但其中的事件子结构体(rev、wev)将在后面单独清零,因此不能丢失对它们的引用。

instance=rev->instance;ngx_memzero(rev,sizeof(ngx_event_t));ngx_memzero(wev,sizeof(ngx_event_t));rev->instance=!instance;wev->instance=!instance;rev->index=NGX_INVALID_INDEX;wev->index=NGX_INVALID_INDEX;rev->data=c;wev->data=c;wev->write=1;
#1 保存旧事件的 instance 值,然后清零读/写事件 #2 将 instance 值取反后分别赋给新事件的 instance 字段 instance 是 Nginx 事件模块中用来解决 “过期事件” 问题的重要机制。 当连接关闭后,其事件结构可能还在 epoll/kqueue 等事件驱动机制中留有未处理的事件。 通过每次重用连接时翻转 instance 值,并在事件回调中校验该值是否与当前连接匹配, 可以安全地丢弃属于上一个连接周期的过期事件。 #3 初始化事件索引与回调数据 将事件的 data 成员指向所属的连接结构 c, 这样在事件回调函数中可以通过 ev->data 取回连接对象。 #4 将写事件的 write 标志置为 1,表明这是一个写事件

7 返回连接指针
returnc;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 13:26:19

基于稀疏训练与结构化剪枝的YOLOv5轻量化改进:原理、代码与实验全解析

摘要 目标检测模型在实际部署中常面临计算资源受限的问题。本文提出一种结合稀疏训练(Sparse Training)与结构化剪枝(Structured Pruning)的YOLOv5改进方案,通过BN层稀疏化诱导通道重要性差异,再以通道级剪枝去除冗余特征图,显著降低模型参数量与计算量。实验表明,在保…

作者头像 李华
网站建设 2026/4/21 13:25:15

《重构:改善既有代码的设计》——以Java之名,重拾代码之美

这不是一本读一遍就够的书,这是一本值得放在手边反复翻阅的编程之道。引子:一本改变了无数程序员的书1999年,Martin Fowler的《Refactoring: Improving the Design of Existing Code》首次面世,在软件开发领域投下了一颗重磅炸弹。…

作者头像 李华
网站建设 2026/4/21 13:22:17

终极Mac抢票指南:如何用12306ForMac轻松购买火车票

终极Mac抢票指南:如何用12306ForMac轻松购买火车票 【免费下载链接】12306ForMac An unofficial 12306 Client for Mac 项目地址: https://gitcode.com/gh_mirrors/12/12306ForMac 作为Mac用户,你是否厌倦了在春运期间与12306网页版搏斗的体验&am…

作者头像 李华
网站建设 2026/4/21 13:20:16

这个问题在开发中,如何选择适合的 API?

开发中选API,千万别只盯着“价格低”这三个字,上线后帮你踩坑的往往就是当初为了省那几块钱选的劣质接口。老手选API,一般都死盯以下四个维度:第一看:返回的字段,是不是你真正想要的 不要只看接口名字叫“查…

作者头像 李华