EventPoller 是 ZLMediaKit/ZLToolKit 网络层的核心引擎,本文从源码逐行分析其在 Linux 下的 epoll 实现,包括事件循环、异步任务、延时队列和退出机制。1. EventPoller 在架构中的位置┌─────────────────────────────────────────────┐ │ 业务层:RtspSession / RtmpSession / ... │ ├─────────────────────────────────────────────┤ │ 网络抽象层:Socket / TcpServer │ ├─────────────────────────────────────────────┤ ← 本篇重点 │ 事件引擎层:EventPoller / EventPollerPool │ ├─────────────────────────────────────────────┤ │ 系统调用层:epoll_create / epoll_ctl / ... │ └─────────────────────────────────────────────┘2. 类结构2.1 继承关系TaskExecutor (线程任务执行器) └─ EventPoller (事件轮询器) └─ EventPollerPool (线程池管理多个 EventPoller)TaskExecutor:继承ThreadPool,提供async()投递任务能力EventPoller:在其基础上增加 epoll 事件循环EventPollerPool:单例,管理多个 EventPoller 实例2.2 EventPoller 核心成员// ZLToolKit/src/Poller/EventPoller.cppclassEventPoller:publicTaskExecutor{public:usingPtr=std::shared_ptrEventPoller;private:int_epoll_fd=-1;// epoll 实例 fdint_pipe_fd[2]={-1,-1};// pipe 用于唤醒 epoll_waitstd::mutex _mtx;// 保护 _event_mapstd::unordered_mapint,PollEventCB_event_map;// fd → 事件回调std::dequePollTaskCB_list_task;// 异步任务队列DelayTaskMap _delay_task_map;// 延时任务(按执行时间排序)bool_exit_flag=false;// 退出标志};3. 构造与初始化EventPoller::EventPoller(ThreadPool::Priority priority){// 1. 创建 epoll 实例_epoll_fd=epoll_create1(EPOLL_CLOEXEC);if(_epoll_fd==-1){throwstd::runtime_error("epoll_create1 failed");}// 2. 创建 pipe 用于唤醒if(pipe(_pipe_fd)!=0){close(_epoll_fd);throwstd::runtime_error("pipe failed");}// 3. 将 pipe 读端注册到 epoll// 当有异步任务投递时,往 pipe 写端写 1 字节,唤醒 epoll_waitaddEvent(_pipe_fd[0],EPOLLIN,[this](intevent){onPipeEvent();});}网络库级调用链:epoll_create1(EPOLL_CLOEXEC)→ 创建 epoll 实例pipe()→ 创建管道作为通知机制epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, _pipe_fd[0], ev)→ 注册管道读端4. runLoop — 事件循环核心voidEventPoller::runLoop(boolis_try){constintmax_events=1024;structepoll_eventevents
ZLMediaKit 源码分析(二):EventPoller 事件循环机制深度分析
EventPoller 是 ZLMediaKit/ZLToolKit 网络层的核心引擎,本文从源码逐行分析其在 Linux 下的 epoll 实现,包括事件循环、异步任务、延时队列和退出机制。1. EventPoller 在架构中的位置┌─────────────────────────────────────────────┐ │ 业务层:RtspSession / RtmpSession / ... │ ├─────────────────────────────────────────────┤ │ 网络抽象层:Socket / TcpServer │ ├─────────────────────────────────────────────┤ ← 本篇重点 │ 事件引擎层:EventPoller / EventPollerPool │ ├─────────────────────────────────────────────┤ │ 系统调用层:epoll_create / epoll_ctl / ... │ └─────────────────────────────────────────────┘2. 类结构2.1 继承关系TaskExecutor (线程任务执行器) └─ EventPoller (事件轮询器) └─ EventPollerPool (线程池管理多个 EventPoller)TaskExecutor:继承ThreadPool,提供async()投递任务能力EventPoller:在其基础上增加 epoll 事件循环EventPollerPool:单例,管理多个 EventPoller 实例2.2 EventPoller 核心成员// ZLToolKit/src/Poller/EventPoller.cppclassEventPoller:publicTaskExecutor{public:usingPtr=std::shared_ptrEventPoller;private:int_epoll_fd=-1;// epoll 实例 fdint_pipe_fd[2]={-1,-1};// pipe 用于唤醒 epoll_waitstd::mutex _mtx;// 保护 _event_mapstd::unordered_mapint,PollEventCB_event_map;// fd → 事件回调std::dequePollTaskCB_list_task;// 异步任务队列DelayTaskMap _delay_task_map;// 延时任务(按执行时间排序)bool_exit_flag=false;// 退出标志};3. 构造与初始化EventPoller::EventPoller(ThreadPool::Priority priority){// 1. 创建 epoll 实例_epoll_fd=epoll_create1(EPOLL_CLOEXEC);if(_epoll_fd==-1){throwstd::runtime_error("epoll_create1 failed");}// 2. 创建 pipe 用于唤醒if(pipe(_pipe_fd)!=0){close(_epoll_fd);throwstd::runtime_error("pipe failed");}// 3. 将 pipe 读端注册到 epoll// 当有异步任务投递时,往 pipe 写端写 1 字节,唤醒 epoll_waitaddEvent(_pipe_fd[0],EPOLLIN,[this](intevent){onPipeEvent();});}网络库级调用链:epoll_create1(EPOLL_CLOEXEC)→ 创建 epoll 实例pipe()→ 创建管道作为通知机制epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, _pipe_fd[0], ev)→ 注册管道读端4. runLoop — 事件循环核心voidEventPoller::runLoop(boolis_try){constintmax_events=1024;structepoll_eventevents