当前位置: 首页 > news >正文

网狐的通过队列实现异步服务的结构理解

核心是使用(IOCP)模型来实现

如上图线程循环中的GetQueuedCompletionStatus,它是 Windows 系统提供的核心 API,用于I/O 完成端口(IOCP)模型中,专门等待异步 I/O 操作(或自定义任务)的完成通知,是高性能网络 / 服务编程的关键接口。

核心功能
  1. 阻塞等待完成通知:调用该函数后,线程会阻塞(可设置超时时间),直到以下任一情况发生:

    • 有异步 I/O 操作(如套接字读写、文件操作)完成,且结果被投递到关联的完成端口;
    • 外部通过PostQueuedCompletionStatus主动投递自定义 “完成通知”(如代码中投递队列任务);
    • 超时(若指定了非INFINITE的超时时间);
    • 完成端口被关闭 / 出错。
  2. 获取完成操作的详细信息:函数通过输出参数返回完成操作的关键信息:

    • lpNumberOfBytesTransferred:实际传输的字节数(如套接字读取的字节数);
    • lpCompletionKey:关联的 “完成键”(自定义上下文,代码中传递了CQueueService*指针);
    • lpOverlapped:异步操作关联的OVERLAPPED结构体(若为自定义投递则为NULL)。
  • 非传统 I/O 场景:代码中并未直接用于网络 / 文件异步 I/O,而是复用 IOCP 模型实现 “任务队列 + 线程池”
    • PostQueuedCompletionStatus向完成端口投递 “队列任务通知”(传递CQueueService*作为上下文);
    • GetQueuedCompletionStatus阻塞等待通知,拿到通知后处理队列中的任务(如定时器、数据库、套接字事件);
    • 利用 IOCP 的 “线程池调度” 特性,实现高效的任务分发(单线程处理队列,也可扩展为多线程)。
关键优势(代码中体现的价值)
  1. 高效的线程调度:IOCP 会自动优化线程唤醒策略,避免 “线程风暴”,适合高并发场景;
  2. 统一的任务分发:无论是系统异步 I/O 还是自定义任务(如代码中的队列事件),都能通过同一个接口等待 / 处理;
  3. 灵活的阻塞 / 超时控制:通过dwMilliseconds参数(代码中用INFINITE永久阻塞),可灵活控制线程等待逻辑。

总结

GetQueuedCompletionStatus核心是为 IOCP 模型提供 “等待 - 获取” 完成通知的能力,既可以处理系统异步 I/O 操作,也可以像示例代码中一样,被复用为 “自定义任务队列” 的核心调度接口,是 Windows 高性能服务 / 网络编程的基石。

  • CQueueServiceThread::RepetitionRun:线程的核心循环函数,本质是一个无限循环 + 阻塞等待(不是 “无限循环被调用”,而是函数内部有循环,且循环里被GetQueuedCompletionStatus卡住);
  • CQueueService::AddToQueue:往队列加任务的函数,其内部一定会调用PostQueuedCompletionStatus(IOCP 的投递接口)—— 这才是 “解除阻塞” 的关键。
完整执行流程(一步一步说)
  1. 初始状态:线程进入阻塞

    • RepetitionRun被调用后,函数内部会进入while(true)这类无限循环;
    • 循环里执行GetQueuedCompletionStatus,此时没有任何 “完成通知” 投递到完成端口,线程会一直阻塞在这里(卡着不动,不会执行循环的下一轮)。
  2. 调用 AddToQueue:解除阻塞的关键

    • 当你调用AddToQueue往队列加任务时,这个函数的核心逻辑是:① 把任务数据写入队列;② 调用PostQueuedCompletionStatus向完成端口主动投递一个 “完成通知”(附带队列上下文、自定义数据等);
    • 一旦PostQueuedCompletionStatus调用成功,完成端口就有了 “待处理的通知”,此时:
    • GetQueuedCompletionStatus立即解除阻塞,返回成功;
    • ✅ 接着执行后续的任务处理逻辑(读取队列数据、调用OnQueueServiceThread处理任务);
    • ✅ 任务处理完后,循环会回到GetQueuedCompletionStatus这一行,再次进入阻塞,等待下一个通知。

举例说明:

假设模块 A 和模块 B 同时调用AddToQueue,整个流程如下:

补充:关于数据的读写

核心逻辑是通过队列存储:取出队列头部数据

CQueueService::GetData的作用就是从任务队列的队首读取并移除数据

  • AddToQueue把任务(模块 A、模块 B 的)依次加入队列时,任务会按 “先加的在前、后加的在后” 排队;
  • GetQueuedCompletionStatus解除阻塞后,调用GetData优先取出队列最前面的那个任务(比如先处理模块 A 的,再处理模块 B 的);
  • 这完全符合 IOCP 模型下 “投递一个通知,处理一个任务” 的逻辑,保证任务按投递顺序处理。
http://www.cnnetsun.cn/news/1285427.html

相关文章:

  • 基于dqn的燃料电池混合动力汽车能量管理策略 1.研究对象为燃料电池-动力电池混合动力汽车 2...
  • 长沙心理医院就诊指南:真实案例分享与暖心复盘
  • 寻找SJZ外挂开发
  • 大学英语四六级考试听力广播系统案例-江西工程职业学院应用海特伟业大学英语四六级考试听力广播系统分析
  • 星形弹性联轴器好用的厂家
  • LangChain Model IO 提示词模版(Python版)
  • 从OpenClaw热潮看制造业AI Agent的架构落地实录
  • 蔚来终于盈利,李斌能开香槟了吗
  • 浏览器api 学习笔记
  • 基于DSC或DSOGI的“三电平逆变器带不平衡负载”仿真研究:SVPWM/SPWM调制与T型/...
  • 计算机毕业设计源码:Python 携程旅游数据分析大屏系统 Django框架 selenium 爬虫 大数据 大模型 数据分析 agent 机器学习 旅行 出游 出行(建议收藏)✅
  • 地球上的硅的储量够造多少倍于现在的芯片
  • 一文讲透|9个降AIGC平台测评:本科生降AI率必备指南
  • Windows桌面审计:用OCR高效提取VHD磁盘内容
  • 【多 Agent 协作系统】架构模式:中心化 vs 去中心化 vs 混合——三种架构的深度对比与选型指南!
  • 两会热议“人工智能+”:AI如何真正扎根工业研发?
  • 2026别错过!更贴合专科生的降AI率网站,千笔·降AI率助手 VS WPS AI
  • 封神!技术面试答“线上紧急故障”,用《孙子兵法》拿捏面试官[特殊字符]
  • Studio Pro 8.0.2专业编曲软件机架软件。直播软件。StudioPro8 For Mac 苹果系统 Win系统专业直播软件下载Mac/Win系统PreSonus Studio Pro 8
  • skillsbot技能库让AI帮你操控浏览器:体验浏览器自动化调度技能,还能截图哦
  • 哲学与AI的交织:理性探索
  • 2026年主流降论文AI率工具实测:哪款效果最好?
  • ​影视飓风Tim探展德施曼AWE展台,联合B站现场解锁AI智能锁新玩法
  • EIG旗下MidOcean Energy将从JERA手中收购Gorgon LNG项目额外权益;双方探讨建立战略联盟
  • 马斯克炸屏警告:拿到枪的猴子正在收割每一个“养虾人”
  • 深度学习入门理解——从概率和信息的角度(数学篇后记)
  • Visual Studio 2013 - 输出窗口一闪而过问题解决
  • Visual Studio 2013 - 高亮设置括号匹配 (方括号)
  • Andrew Ng深度学习课程终极指南:Coursera Deep Learning Specialization全面解析
  • Dolt:数据版的Git,让数据库管理更智能