仿muduo实现高并发服务器——EventLoop.hpp初步设计(未纳入超时管理模块)

目录

摘要

EventLoop.hpp 把线程内的任务队列与 Poller 合成一个调度单位:_thread_id 标所属线程,_event_fd 用 eventfd 打断 epoll_wait,_mutex 保护 vector 型 _tasks,另有 _poller 与 _event_channel。Start() 依次 Poll 取活跃集、HandleEvent() 分发、RunAllTask() 清队列。

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

注释

3.1 设计点

  1. 便于管理内部数据为先,结构开销其次,故任务队列用 vector 而非 queue。2. 本模块做的是「线程单位内」与「任务队列」的调度,集成 Poller、Channel、_tasks(临界资源):2.1 因在线程内,故有 _thread_id 标识所属线程;2.2 因 Poller 会异步阻塞,故用 eventfd 防未就绪事件一直阻塞;2.3 因有 _tasks,必须用 mutex 保护临界资源;2.4 因要维护 eventfd 的读写,才引入 Channel;2.5 引入 Poller 只为管理 fd 的 EPOLL 系列。3. 超时管理暂未纳入。

3.2 误区

unique_ptr 等智能指针一定先调智能指针自身的构造,之后才决定是否调指向类型的构造,优先顺序别搞混。

3.3 新知识

  1. 勿穷究,找适当:_event_channel 只管 eventfd 的读、写及 CallBack,别把它的 Poller 与 EventLoop::_poller 综合来看,不必追求完美。2. 看完一个模块再下手写,切勿提早写,重要⚠️。

正文

构造先取 _thread_id,再 eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK),失败即 abort(),随后 make_unique<Channel>(_event_fd, this)------旧写法传的是 &_poller,行内注释说明任务要跨线程故传 this;EnableRead() 内部已自动 Update,末尾 SetReadCB。ReadEventfd 读出 uint64_t 消耗累加值,WeakUpEventfd 写入 1。Push 在锁内 push_back 后调 WeakUpEventfd(行内 TODO 存疑);PushTaskqueue 同线程直跑,否则入队;RunAllTask 锁内 swap 到临时 vector、出锁逐个执行;析构仅把 _event_fd = -1。

bug1:gcc 无法定位 ReadEventfd 函数的「位置」。先写 std::bind(ReadEventfd, this),再改 std::bind(EventLoop::ReadEventfd, this) 仍不行;取成员函数指针必须用 &类名::函数名,& 不能省略,故最终为 std::bind(&EventLoop::ReadEventfd, this)。

总结

取舍是管理优先于结构开销:vector 作队列、swap 后出锁执行、eventfd 打通阻塞;bug1 属成员函数指针语法。

常见问题

  1. _tasks 为何用 vector?见 3.1 第 1 点。
  2. RunAllTask 为何 swap 后出锁执行?执行在锁外,不持锁跑业务。
  3. bug1 的 & 加在哪?SetReadCB 中 bind 的首参。

标签

C++、epoll、eventfd、任务队列、成员函数指针

【统计:全文约 700 字 / 原代码 154 行 / 比例约 4.5;注释字段小节 3 个 / 成文 bug 1 处】(字数不含代码块与头部图片、目录标记)

相关推荐
分布式存储与RustFS4 小时前
群晖 NAS 被 C3RB3R 锁了:本地备份一起被加密,RustFS 对象锁为什么删不掉
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
真好啊又活了一天4 小时前
服务器和虚机配置IPV6
运维·服务器·github
zixu_star4 小时前
定时任务是什么?从日常自动化到 AI 应用,软件如何自动执行任务?
运维·人工智能·自动化
AR-26710-5 小时前
Linux Day33——定时任务+lvm
linux·运维
墨痕诉清风5 小时前
SSRF漏洞实战记录+OSS桶命令执行+MCP漏洞
linux·服务器·数据库
润滑卫士5 小时前
液压系统工作粘度窗口等级选型:泵允许粘度范围与油温-粘度匹配计算
运维
布莱克6056 小时前
Swift 常量详解:从 let 到编译期优化
服务器·开发语言·ssh·swift·常量·let
测试界的小码农8 小时前
【Linux 命令实战(04):文件内容查看,掌握 cat、less、head、tail】
linux·服务器·less
每月一号准时摆烂8 小时前
服务器运维笔记(一)——使用shell编写实时查看BMC功率的脚本
运维·服务器·笔记
时间售卖铺9 小时前
Chrony与SSH实战:精准时间同步与安全远程登录
运维·安全·云原生·ssh