ZLToolKit 源码分析(五):EventPoller 事件轮询器实现
2026/6/4 4:24:01 网站建设 项目流程

EventPoller 是 ZLToolKit 最核心的组件,将 epoll/kqueue/select 统一抽象为 Reactor 模型。本文从跨平台封装到 epoll 系统调用,逐层拆解其实现。

1. 跨平台 IO 多路复用抽象

1.1 编译期平台选择

// EventPoller.cpp#ifdefined(__linux__)&&!defined(ENABLE_EPOLL_FALLBACK)#defineHAS_EPOLL1#elifdefined(__APPLE__)||defined(__FreeBSD__)||defined(__OpenBSD__)#defineHAS_KQUEUE1#else#defineHAS_SELECT1#endif
平台实现系统调用
Linuxepollepoll_create1 / epoll_ctl / epoll_wait
macOS/BSDkqueuekqueue / kevent
Windows/othersselectselect

1.2 接口统一

classEventPoller:publicThreadPool{public:// 添加 fd 事件监听intaddEvent(intfd,intevent,PollEventCB&&cb);// 删除 fd 事件监听booldelEvent(intfd,PollCompleteCB&&cb=nullptr);// 修改 fd 事件intmodifyEvent(intfd,intevent);// 异步任务Task::Ptrasync(TaskInCB&&task,boolmay_sync=true)override;// 延时任务DelayTask::PtrdoDelayTask(uint64_tdelay_ms,function<uint64_t()>&&task)override;// 事件循环voidrunLoop(boolis_try=false);};

上层代码只需调用addEvent/delEvent/modifyEvent,不需关心底层是 epoll 还是 select。

2. EventPoller 构造

EventPoller::EventPoller(conststring&name,Priority priority,boolbind_cpu){// 1. 创建 epoll 实例#ifdefined(HAS_EPOLL)_epoll_fd=epoll_create1(EPOLL_CLOEXEC);if(_epoll_fd<0){throwruntime_error("epoll_create1 failed");}#elifdefined(HAS_KQUEUE)_epoll_fd=kqueue();// ...#else// select 模式无专用 fd#endif// 2. 创建通知管道if(pipe(_pipe_fd)!=0){throwruntime_error("pipe failed");}// 3. 将管道读端注册到 epolladdEvent(_pipe_fd[0],EPOLLIN,[this](intevents){onPipeEvent();});// 4. 启动工作线程// ThreadPool 基类中 _threads[i] = new thread(runLoop)// 5. CPU 亲和性if(bind_cpu){setCPUAffinity(thread_index);}}

系统调用链

epoll_create1(EPOLL_CLOEXEC) → _epoll_fd pipe2(_pipe_fd, O_CLOEXEC) → 通知管道 epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, _pipe_fd[0], EPOLLIN)

3. addEvent / delEvent / modifyEvent

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询