news 2026/5/9 1:51:16

ngx_handle_read_event

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ngx_handle_read_event

1 定义

ngx_handle_read_event 函数 定义在 ./nginx-1.24.0/src/event/ngx_event.c
ngx_int_tngx_handle_read_event(ngx_event_t*rev,ngx_uint_tflags){if(ngx_event_flags&NGX_USE_CLEAR_EVENT){/* kqueue, epoll */if(!rev->active&&!rev->ready){if(ngx_add_event(rev,NGX_READ_EVENT,NGX_CLEAR_EVENT)==NGX_ERROR){returnNGX_ERROR;}}returnNGX_OK;}elseif(ngx_event_flags&NGX_USE_LEVEL_EVENT){/* select, poll, /dev/poll */if(!rev->active&&!rev->ready){if(ngx_add_event(rev,NGX_READ_EVENT,NGX_LEVEL_EVENT)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}if(rev->active&&(rev->ready||(flags&NGX_CLOSE_EVENT))){if(ngx_del_event(rev,NGX_READ_EVENT,NGX_LEVEL_EVENT|flags)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}}elseif(ngx_event_flags&NGX_USE_EVENTPORT_EVENT){/* event ports */if(!rev->active&&!rev->ready){if(ngx_add_event(rev,NGX_READ_EVENT,0)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}if(rev->oneshot&&rev->ready){if(ngx_del_event(rev,NGX_READ_EVENT,0)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}}/* iocp */returnNGX_OK;}
ngx_handle_read_event 函数 根据当前使用的事件驱动机制(边沿触发、水平触发、事件端口、IOCP), 统一管理读事件在内核监听中的添加与删除,确保事件既不丢失也不反复通知,同时避免忙轮询。

2 详解

1 函数签名

ngx_int_tngx_handle_read_event(ngx_event_t*rev,ngx_uint_tflags)
返回值 NGX_OK:操作成功。 NGX_ERROR:操作失败。
参数 1 ngx_event_t *rev 指向要监听的事件 参数 2 ngx_uint_t flags 传递额外的控制标志,影响函数对事件的处理策略

2 逻辑流程

1 边沿触发模式 2 水平触发模式 3 event ports 4 iocp

{if(ngx_event_flags&NGX_USE_CLEAR_EVENT){/* kqueue, epoll */if(!rev->active&&!rev->ready){if(ngx_add_event(rev,NGX_READ_EVENT,NGX_CLEAR_EVENT)==NGX_ERROR){returnNGX_ERROR;}}returnNGX_OK;}elseif(ngx_event_flags&NGX_USE_LEVEL_EVENT){/* select, poll, /dev/poll */if(!rev->active&&!rev->ready){if(ngx_add_event(rev,NGX_READ_EVENT,NGX_LEVEL_EVENT)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}if(rev->active&&(rev->ready||(flags&NGX_CLOSE_EVENT))){if(ngx_del_event(rev,NGX_READ_EVENT,NGX_LEVEL_EVENT|flags)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}}elseif(ngx_event_flags&NGX_USE_EVENTPORT_EVENT){/* event ports */if(!rev->active&&!rev->ready){if(ngx_add_event(rev,NGX_READ_EVENT,0)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}if(rev->oneshot&&rev->ready){if(ngx_del_event(rev,NGX_READ_EVENT,0)==NGX_ERROR){returnNGX_ERROR;}returnNGX_OK;}}
#1 判断是否为边沿触发模式: ngx_event_flags 是全局变量, 记录了当前事件模块的特性位掩码。 NGX_USE_CLEAR_EVENT 置位表示使用 边沿触发机制。 该模式只通知一次事件就绪,不会重复通知。
注释:提示该分支对应 FreeBSD 的 kqueue 和 Linux 的 epoll。
条件判断: rev->active 表示该读事件是否已被加入内核事件监听集合; rev->ready 表示内核已将该事件标识为就绪 仅当事件既没有被监听,也没有待处理的就绪状态时,才需要重新添加事件监听。
添加事件并检查结果: 调用 ngx_add_event 将读事件加入内核监听, 事件类型为 NGX_READ_EVENT, 标志为 NGX_CLEAR_EVENT(边沿触发)。 若返回值等于 NGX_ERROR, 表明添加失败 添加失败立即返回错误, 由上层调用者处理
边沿触发分支成功返回: 事件要么已处于正确监听状态, 要么刚被成功添加。
#2 判断是否为水平触发模式: 若 ngx_event_flags 中 NGX_USE_LEVEL_EVENT 置位, 表示当前使用 水平触发机制。 该模式下只要有数据可读,内核会一直通知。
与边沿触发分支相同: 当事件未被监听且未就绪时, 才需要向内核注册监听。
判断是否需要删除事件: 在水平触发模式下, 若事件仍在监听(active 为真), 且 已经就绪(ready 为真) 或 调用者要求关闭(flags 包含 NGX_CLOSE_EVENT), 则必须从内核监听集合中移除该事件。 就绪时不删除: 内核会不断通知,导致事件循环忙轮询(busy loop)。 关闭时不删除:可能触发无效事件甚至访问已释放资源。
删除读事件: 调用 ngx_del_event 移除该读事件。 标志位通过 NGX_LEVEL_EVENT | flags 组合传入, 以便底层(如 poll)可以根据 NGX_CLOSE_EVENT 跳过某些清理。
#3 判断是否为 event ports 模式: Solaris 的 event ports 机制, 行为类似边沿触发,但支持一次性事件(oneshot)。 NGX_USE_EVENTPORT_EVENT 置位时使用该分支。

4 iocp
/* iocp */returnNGX_OK;}
IOCP 下读写都由异步提交操作驱动, 无需显式添加/删除监听事件。 所有未显式返回的路径统一至此返回成功。 这包括: IOCP 模式直接执行到此处。 水平触发模式下 active 为假,或 active 为真但未就绪且无关闭标志。 event ports 模式下 oneshot 或 ready 为假。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 1:51:16

PullWeights MCP Server:AI模型仓库的MCP协议集成实践

1. 项目概述:一个为AI模型仓库打造的“万能钥匙” 如果你和我一样,日常开发中经常需要在Claude Desktop、Cursor这类智能IDE里,和不同的AI模型打交道——比如想快速搜索一个最新的Llama 3.1模型,或者把本地微调好的模型推送到云端…

作者头像 李华
网站建设 2026/5/9 1:46:31

Council框架:构建多AI智能体协作系统的工程实践指南

1. 项目概述:一个面向AI代理的“议会”框架最近在折腾AI应用开发的朋友,可能都遇到过类似的困境:单个大语言模型(LLM)能力再强,面对复杂任务时也常常显得力不从心。比如,你需要它分析一份市场报…

作者头像 李华
网站建设 2026/5/9 1:46:30

AI智能体在宝可梦对战中的实践:从规则引擎到强化学习

1. 项目概述:当宝可梦遇上AI智能体 最近在GitHub上看到一个挺有意思的项目,叫 leoakok/poke-agents 。光看名字,你可能以为这是个宝可梦游戏的外挂或者脚本,但点进去仔细研究后,我发现它的内核远比想象中要酷。简单…

作者头像 李华
网站建设 2026/5/9 1:45:30

ARM浮点运算指令集详解与应用优化

1. ARM浮点运算指令集概述在现代处理器架构中,浮点运算能力是衡量计算性能的关键指标之一。作为移动和嵌入式领域的主导架构,ARM提供了丰富的浮点运算指令集,涵盖了从基本算术运算到复杂格式转换的全套操作。这些指令不仅支持传统的单精度&am…

作者头像 李华
网站建设 2026/5/9 1:40:37

AI编程助手代码补丁自动应用:JAI Diff Editor与lite-diff规范详解

1. 项目概述:当AI助手遇上代码补丁,如何优雅地“一键应用”?如果你和我一样,日常开发中重度依赖Claude、Cursor这类AI编程助手,那你一定遇到过这个让人又爱又恨的场景:AI助手在聊天窗口里给你生成了一段完美…

作者头像 李华
网站建设 2026/5/9 1:40:30

ARM虚拟中断与中断路由服务(IRS)架构解析

1. 虚拟中断与中断路由服务(IRS)架构概述中断路由服务(Interrupt Routing Service, IRS)是现代计算机系统中管理硬件中断的核心机制,特别是在虚拟化环境中扮演着关键角色。在ARM架构下,IRS通过虚拟中断状态表(Interrupt State Table, IST)实现对虚拟机(V…

作者头像 李华