1.7.C++项目:仿muduo库实现并发服务器之Poller模块的设计

项目完整在:

文章目录

  • 一、Poller模块:描述符IO事件监控模块
  • 二、提供的功能
  • 三、实现思想
    • (一)功能
    • (二)意义
    • (三)功能设计
  • 四、封装思想
  • 五、代码
    • (一)框架
    • (二)完整代码

一、Poller模块:描述符IO事件监控模块

在这里插入图片描述

二、提供的功能

对任意的描述符进行IO事件监控。

三、实现思想

(一)功能

对任意的描述符进行IO事件监控。

(二)意义

对epoll进行的封装,让对描述符进行事件监控的操作更加简单。文章来源地址https://uudwc.com/A/W1nmm

(三)功能设计

  1. 添加事件监控—— channel模块
  2. 修改事件监控
  3. 移除事件监控
  4. 取消定时任务

四、封装思想

封装思想: 1. 必须拥有一个epoll的操作句柄
         2. 拥有一个struct epoll_event 结构数组,监控保存所有的活跃事件!
         3. 使用hash表管理描述符与描述符对应的事件管理Channnel对象!
逻辑流程:
         1. 对描述符进行监控,通过Channnel才能知道描述符监控什么事件
         2. 当描述符就绪了,通过描述符在hash表中找到对应的Channel(得到了Channel才知道什么事件如何处理)当描述符就绪了,返回就绪描述符对应的Channel

五、代码

(一)框架

框架:
class Poller {
private:
        int _epfd;
        struct epoll_event_evs[xxx];
        std::unordered_map<int,Channel*> mp;
private:
        // 1. 判断要更新事件的描述符是否存在
        // 2. 针对epoll直接操作(添加,修改,移除)
public:
        // 1. 添加或者更新描述符所监控的事件
        void Update(Channel* channel);
        // 2. 移除描述符所监控的事件
        void Remove(Channel* )
        // 3. 开始监控,获取就绪Channel
};
*/
/*

(二)完整代码

#define MAX_EPOLLEVENTS 1024
// Poller模块是对epoll进⾏封装的⼀个模块,主要实现epoll的IO事件添加,修改,移除,获取活跃连接功能。
class Poller {
private:
        int _epfd;
        struct epoll_event _evs[MAX_EPOLLEVENTS];
        std::unordered_map<int,Channel*> _channels;
private:
        // 对epoll直接操作
        void Update(Channel* channel,int op) {
                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!!!");
                        abort(); // 推出程序!!
                }
        }
        // 判断一个Channel是否已经添加到了事件监控
        bool hashChannel(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 = hashChannel(channel);
                if (ret == false) {
                       
                        _channels.insert(std::make_pair(channel->Fd(),channel));
                         return Update(channel,EPOLL_CTL_ADD); // 不存在添加
                }
                return 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\n", strerror(errno));
                abort();//退出程序
            }
            for (int i = 0; i < nfds; i++) {
                auto it = _channels.find(_evs[i].data.fd);
                assert(it != _channels.end());
                it->second->setRevents(_evs[i].events);//设置实际就绪的事件
                active->push_back(it->second);
            }
            return;
        }
};

原文地址:https://blog.csdn.net/weixin_54447296/article/details/133497920

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

上一篇 2023年10月29日 15:10
【数据结构】排序(1) ——插入排序 & 希尔排序
下一篇 2023年10月29日 16:10