当前位置: 首页 > news >正文

C++仿muduo库高并发服务器项目:Poller模块

前言

本篇文章所讲的是本人的个人项目仿muduo库高并发服务器中的Poller模块实现部分。

Poller模块介绍:

这也是一个比较简单的基础功能模块,主要提供对epoll系统调封装的接口。

  • 功能:对任意描述符进行IO事件监控
  • 意义:封装epoll,简化描述符事件监控操作
  • 功能接口:
    1. 添加事件监控(针对Channel模块 )
    2. 修改事件监控
    3. 移除事件监控

Channel模块启用监控、移除监控等功能,都是通过调用该模块的封装完成的。

模块设计

  1. 需具备 epoll 的操作句柄。
  2. 拥有 struct epoll_event 结构数组,用于监控时保存所有活跃事件。
  3. 利用哈希表管理描述符及其对应的事件管理 Channel 对象。

逻辑流程

  1. 对描述符进行监控,通过 Channel 明确描述符需要监控的事件。
  2. 当描述符就绪时(描述符有事件就绪时),借助哈希表根据描述符找到对应的 Channel(通过 Channel 确定事件的处理方式),并返回就绪描述符对应的 Channel
const int MAX_EPOLLEVENTS = 1024;
class Poller
{
private:int _epfd;                                      //epoll文件描述符struct epoll_event _evs[MAX_EPOLLEVENTS];       //存放就绪事件的数组std::unordered_map<int,Channel*> _channels;     //建立epfd到channel指针的映射//对epoll的直接操作void Update(Channel* channel,int op){// int epoll_ctl(int epfd, int op,  int fd,  struct epoll_event *ev);int fd = channel->Fd();struct epoll_event ev;ev.data.fd = fd;ev.events = channel->Events();int ret = epoll_ctl(_epfd,op,fd,&ev);if(ret < 0){ERR_LOG("EPOLLCTL FAILED!!");}}//判断一个Channel是否已经添加了事件监控bool HasChannel(Channel* channel){auto it = _channels.find(channel->Fd());if(it == _channels.end()){return false;}return true;}
public:Poller(){_epfd = epoll_create(MAX_EPOLLEVENTS);if(_epfd < 0){ERR_LOG("EPOLL CREATE FAILED!!");abort();//直接退出}}//添加或者修改监控事件void UpdateEvent(Channel* channel){bool ret = HasChannel(channel);if(ret == false){//不存在则添加_channels.insert(std::make_pair(channel->Fd(),channel));Update(channel,EPOLL_CTL_ADD);}//存在则修改Update(channel,EPOLL_CTL_MOD);}//移除监控void RemoveEvent(Channel* channel){auto it = _channels.find(channel->Fd());if(it != _channels.end()){_channels.erase(it);}Update(channel,EPOLL_CTL_DEL);}//开始监控,返回活跃连接void Poll(std::vector<Channel*>* active){// int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)int nfds = epoll_wait(_epfd,_evs,MAX_EPOLLEVENTS,-1);//阻塞模式if(nfds < 0){if(errno == EINTR){return;}ERR_LOG("EPOLL WAIT ERROR:%s",strerror(errno));abort();}for(int i = 0;i < nfds;i++){auto it = _channels.find(_evs[i].data.fd);assert(it != _channels.end());it->second->SetEvents(_evs[i].events);//设置实际就绪事件active->push_back(it->second);}}
};
http://www.dtcms.com/a/601052.html

相关文章:

  • QT C++ QWebEngine与Web JS之间通信
  • 华为防火墙web配置SSL-在外人员访问内网资源
  • 本地部署事务管理软件 JIRA 并实现外网访问(Windows 版本)
  • 18、Linux常用命令-磁盘分区相关命令
  • nvm与node.js的安装指南
  • python+django/flask+vue的书城图书阅读器系统,亮点含目录章节pycharm
  • 外贸cms什么意思seo海外推广
  • C++网络开发---CURL与CURLcode数据类型
  • 【Python数据分析】数据分析与可视化
  • MyBatis概述
  • Hadoop集群搭建(下):centos 7为例(已将将安装所需压缩包统一放在了/opt/software目录下)
  • 美创网站建设优势开县网站制作
  • 北京市网站建设网站怎么盈利的
  • 2.6、安全大脑:AI驱动的安全编排与自动化响应实战
  • Linux 进程间通信怎么选?——场景化决策指南
  • 折800网站源码石家庄新闻发布会
  • ThreadLocal 中弱引用(WeakReference)设计:为什么要 “故意” 让 Key 被回收?
  • Java大厂面试真题:从Spring Boot到AI微服务的三轮技术拷问
  • es开源小工具 -- 分析器功能
  • MQTT 与双工通信
  • 【.NET10】正式发布!微软开启智能开发生态新纪元
  • Linux 魔法:多种空块填充技术详解与实践
  • 深入浅出 SQLSugar:快速掌握高效 .NET ORM 框架
  • 广东哪家网站建网站搜索不到公司网站
  • 做网站开发需要学什么app开发自学教程
  • 【Linux】网络编程入门:从一个小型回声服务器开始
  • 【统一功能处理】从入门到源码:拦截器学习指南(含适配器模式深度解读)
  • linux 解析并生成一个platform_device设备具体过程
  • 编译器使用的开发语言 | 解析编译器的实现原理及其开发语言的选择
  • 佛山企业网站建设流程织梦营销型网站模板