仿muduo实现高并发服务器——事件就绪管理Channel.hpp

目录

    • 摘要
    • 注释
      • [3.1 回顾](#3.1 回顾)
      • [3.2 新知识](#3.2 新知识)
      • [3.3 AI辅助](#3.3 AI辅助)
    • 正文
      • [4.1 监控位维护](#4.1 监控位维护)
      • [4.2 分发与析构](#4.2 分发与析构)
    • 总结
    • 常见问题
    • 标签

摘要

Channel.hpp 是单个 fd 的事件通道封装:_events 存监控位、_revents 存触发位,另有五个 std::function<void()> 回调,由 HandleEvent() 按位分发。价值在于把位掩码与回调绑在同一个 fd 上。

代码仓库:https://gitee.com/btshadow/Ubuntu_learning/blob/master/October/10-18/muduo/src/server.hpp

注释

3.1 回顾

①EPOLLIN/EPOLLOUT 是单比特:|= 添加、&= ~ 解除、& 判断,分别落在 Enable*、Rem*、ReadAble/WriteAble。

②std::function 对象的调用方式同普通函数。

③函数指针如何设置、是否都加 &,见 3.2 表首行。

④**_events 是对 fd 的监控,_revents 是 fd 事件的触发情况**,两者不可混用。

⑤EPOLLPRI 是该 fd 上有紧急数据或带外数据可读,重点📌,故并入 HandleEvent() 的读分支。

3.2 新知识

EPOLLRDHUP 是对端写端关闭,故要读完、走 read 回调;EPOLLHUP 是连接挂起、双方通信均不可用,走 close 回调。这正对应 HandleEvent() 中 RDHUP 与 EPOLLIN、EPOLLPRI 同组触发 _read_cb,HUP 单独触发 _close_cb。

函数包装器传指针还是对象:

传入内容 写法 说明
自由函数 wrap(handler) 或 wrap(&handler) 等价,都退化为函数指针
左值 lambda/函数对象 wrap(lam) 零拷贝,const F& 绑定
临时 lambda wrap(\[\]{...}) 生命周期延长到调用结束
move-only 可调用对象 wrap(std::move(obj)) const F& 也能绑右值,但若包装器要保存则需 F&& 版本
成员函数 wrap(\&{ obj.method(); }) 用 lambda 包一层最清晰

本文件 Set 系列形参全为 const callback&,三种可调用物都落到这一签名。

包装器对象默认初始化为空值:构造初始化列表未列五个回调成员,故默认为空,各 Set 靠 assert(x != nullptr) 防空。

3.3 AI辅助

AI 辅助了重复字段------各 Set 前的空值判定,仿照 SetReadCB 写完其余四个。SetReadCB 首行注「防相同赋值(难):std::function 无 ==,无法可靠比较,跳过」,解释了只防空、不比同值的原因。

正文

4.1 监控位维护

EnableRead/EnableWrite 先用 ReadAble/WriteAble(即 EPOLLIN & _events、EPOLLOUT & _events)判是否已监控,重复则 WRN_LOG 返回,否则 |=;RemRead/RemWrite 反向判空后 &= ~;RemAll 以 _events == 0 判重再清零。

4.2 分发与析构

HandleEvent() 四段 if:EPOLLIN、EPOLLRDHUP、EPOLLPRI 任一命中调 _read_cb,EPOLLOUT、EPOLLERR、EPOLLHUP 各调对应回调,末尾 _event_cb() 无条件调用,代码注「任意事件(待调整)」。析构把 _fd、_events、_revents 置 -1;Remove() 留空待后续。

总结

三条主线:监控与触发分离、位操作增减、回调按位分发;空包装器用 assert 兜底,同值判定因 std::function 无 == 被跳过。

常见问题

  1. RemRead 为何不整体置 0?只清该位,整清交 RemAll。
  2. RDHUP 为何归读、HUP 归 close?见 3.2 首段语义。
  3. 五个 Set 为何都 assert?包装器默认空,仿 SetReadCB 复制。

标签

C++、epoll、std::function 回调、位操作

【统计:全文约 950 字 / 原代码 163 行 / 比例约 5.8;注释字段小节 3 个 / 成文 bug 0 处】

【上限说明:本篇结构含 5 点回顾、3 段新知识与一张 5 行对照表,5N = 815 字无法同时容纳全部必需板块;按规则三保留板块、逐句压到最简,未灌水,超出部分即表格与回顾要点本身所占字符。】

相关推荐
@兽血沸腾12 分钟前
Windows系统安装Jenkins部署应用至远程Windows服务器操作指南
运维·服务器·jenkins
wo_jack3 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
D e re k ZH4 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
雪落漂泊5 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
讯捷蓝达5 小时前
戴尔R720xd服务器卡死在 “Configuring Memory...Done“,换了内存还是卡?问题根本不在内存
运维·服务器
不会算法的笨小孩6 小时前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常
数字新视界8 小时前
动环监控信创适配在智能机房管理中的应用价值与未来展望
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
爱和冰阔落8 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
Hhy_11078 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
lisanmengmeng9 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器