muduo网络库(六):Poller类与IO复用 muduo网络库六Poller类与IO复用muduo网络库六Poller类与IO复用概述EpollPoller 子类核心方法Channel 与 epoll_event 的绑定机制newDefaultPoller 为什么单独放在一个文件中精髓总结muduo网络库六Poller类与IO复用概述Poller是 muduo 网络库中IO 复用机制的抽象层它封装了不同的多路复用技术如 epoll、poll、select为上层提供统一的接口。EpollPoller是其基于 Linux epoll 实现的具体子类。在Poller类中只有两个核心成员一个channels_Map存储当前所有的 Channel一个loop_指针标识当前所属的 EventLoop其余都是纯虚函数因为每种具体的多路复用技术epoll、poll 等都有各自的实现逻辑。EpollPoller 子类EpollPoller是对 epoll 的封装因此有两个关键成员epollFd_epoll 的监听文件描述符作为监听仓库events_vectorepoll_event保存 epoll_wait 返回的事件容器核心方法1. updateChannel()先把新 Channel 加入到channels_Map 中删除则修改 index然后根据 Channel 的状态调用 epoll 的update函数即epoll_ctl。状态转换逻辑如下kNew未注册→ 加入 channels Map → 变为kAddedkAdded已注册→ 如果无感兴趣事件isNoneEvent()→EPOLL_CTL_DEL→ 变为kDeletedkAdded→ 如果有事件变更 →EPOLL_CTL_MODkDeleted已删除→ 重新添加 →EPOLL_CTL_ADD→ 变为kAdded通过 Channel 的index_成员来标识它在 epoll 中的状态从而决定是添加、修改还是删除。2. removeChannel()从channels_Map 中删除指定的 Channel同时从 epoll 中删除。3. poll()调用epoll_wait()函数监听所有已注册的 fd。要监听的 fd 已经通过updateChannel加入到epollFd_中了。返回结果存储在events_中必要时会动态扩容。4. fillActiveChannels()遍历events_由于epoll_event结构中的data.fd和data.ptr指向的 Channel 都是绑定的直接将data.ptr转换为Channel*加入到activeChannels中即可。后续在EventLoop::loop()中遍历activeChannels调用Channel::handleEvent()处理事件。注意Poller 只是监听 fd当监听到可读事件后上层调用accept()才真正建立连接。Poller 相当于只负责监听当前线程的 fd构建 channels是 EventLoop 的一部分。Channel 与 epoll_event 的绑定机制Poller结合EpollPoller将 epoll 机制封装每个 EventLoop 只有一个 Poller用于监听所有 Channel。核心在于利用epoll_event.data.ptr将 Channel 和 epoll 监听的事件绑定起来。注册时绑定structepoll_eventevent;event.eventschannel-events();event.data.ptrchannel;// 将 Channel 指针存入 epoll_event::epoll_ctl(epollFd_,operation,fd,event);事件触发时取回Channel*channelstatic_castChannel*(events_[i].data.ptr);这样就将事件 Channel 与 IO 多路复用机制联系了起来而它们都在 EventLoop 类中协作。newDefaultPoller 为什么单独放在一个文件中DefaultPoller::newDefaultPoller()是一个工厂方法用于动态选择 IO 复用实现根据环境变量MUDUO_USE_POLL决定使用哪种 IO 复用方式解耦架构EventLoop 不需要直接依赖具体的 epoll 或 poll 实现通过工厂方法获取。本项目中只实现了 epoll所以默认返回EpollPoller这体现了依赖倒置原则抽象不依赖于具体具体依赖于抽象。单独放在一个文件中的关键原因是避免循环依赖如果把newDefaultPoller放在Poller.cc中实现Poller.cc需要包含具体子类的头文件#include EPollPoller.h而EPollPoller.h又需要继承Poller包含#include Poller.h这就形成了循环依赖导致编译失败。Poller.h (抽象基类) ↑ 继承 EPollPoller.h DefaultPoller.cc (工厂方法) → 包含 Poller.h 和 EPollPoller.h → 负责创建具体实例将工厂方法单独放在DefaultPoller.cc中打破了这种循环依赖让架构更加清晰。精髓总结Poller 类的设计体现了几个关键思想多态抽象Poller定义统一接口EpollPoller提供具体实现上层代码不感知底层细节epoll_event.data.ptr 绑定巧妙利用 epoll 的data.ptr字段将事件和 Channel 直接关联零开销取回工厂模式解耦newDefaultPoller单独编译避免循环依赖遵循依赖倒置原则每个 EventLoop 一个 Poller符合 One Loop Per Thread 模型线程内无需加锁

相关新闻

最新新闻

电信行业项目管理全链路数字化怎么选?一家年项目额超十亿电信企业500+项目一体化管控的选型分析

电信行业项目管理全链路数字化怎么选?一家年项目额超十亿电信企业500+项目一体化管控的选型分析

一、行业现状与数字化痛点 当前,电信领域的数字化转型正面临严峻挑战。行业整体数字化渗透率偏低,大量机构仍在使用纸质台账、Excel或分散的独立系统进行日常管理。从行业共性痛点来看,核心挑战集中在以下几个方面。 第一,数据孤岛…

2026/7/23 3:53:57
深入解析以太网DMA与描述符机制:从原理到嵌入式网络驱动实践

深入解析以太网DMA与描述符机制:从原理到嵌入式网络驱动实践

1. 项目概述与核心价值在嵌入式网络开发,尤其是涉及微控制器(MCU)的场景里,如何高效、稳定地处理海量的网络数据包,一直是工程师面临的核心挑战。CPU如果被频繁的网络数据搬运中断,整个系统的实时性和处理能…

2026/7/23 3:53:57
Claude Code安全漏洞解析与企业防护方案

Claude Code安全漏洞解析与企业防护方案

1. Claude Code安全事件深度解析2026年7月,阿里巴巴内部突然宣布全面禁用Anthropic旗下Claude系列产品,包括Claude Code、Sonnet、Opus等多个AI工具。这一禁令源于Claude Code被曝存在严重的安全漏洞和后门风险,其中最引人关注的是两个高危漏…

2026/7/23 3:53:57
【ollama】自定义结构化输出

【ollama】自定义结构化输出

自定义字段 models.py from typing import Union, Literal from pydantic import BaseModel, Fieldclass sendGroupMsg(BaseModel):type: Literal[send_group_msg] Field(description"指令类型标识,固定为 send_group_msg")carenum: str Field(descript…

2026/7/23 3:53:57
2026写小说软件盘点:亲测10款AI生成小说工具(内含避坑建议)

2026写小说软件盘点:亲测10款AI生成小说工具(内含避坑建议)

最近带新人发现卡文是最大的痛点。大家天天催出教程教你如何写小说,其实思路不畅时利用写小说软件能省下大量时间。很多朋友不知道新手如何开始写小说,在第一步就被劝退。 今天我把半年测试过的10款工具盘点出来,帮你找到适合的写小说的软件&…

2026/7/23 3:53:57
AI工具如何提升本科生论文写作效率与质量

AI工具如何提升本科生论文写作效率与质量

1. 本科生论文写作的痛点与AI工具的价值写论文对本科生来说就像第一次独自远行——明明知道目的地在哪里,却总在找路标时迷路。从开题报告到文献综述,从数据收集到格式调整,每个环节都可能成为拦路虎。去年指导毕业论文时,我发现学…

2026/7/23 3:48:57

月新闻