手写muduo网络库剖析——事件监听器Poller基类

概要

Poller基类定义了监听所有channel通道的监听者应该干哪些事情,是一个抽象类可以由Pollpoller和Epollpoller来继承实现重写里面的方法(IO复用基类,纯虚基类),它积极地监听着所有channel通道所发生的事情,并实时反应到channel,让channel update。是muduo库中多路事件分发器的核心IO复用模块(开启事件循环epollwait)

框架与细节

成员

protected:
    //map的key:sockfd,channel的成员变量之一  value: sockfd所属的channel通道类型
    using ChannelMap = std::unordered_map<int,Channel*>;//无序,hash表
    ChannelMap channels_;
private:
    EventLoop*ownerLoop_;//定义Poller所属的事件循环Eventloop

channels_ 为哈希表,key 为 fd,val 为 channel,protected属性,让子类可以O(1)查找Poller中是否在监听某个channel。

private属性中,有一个EventLoop指针对象,代表Poller属于哪个EventLoop。

方法

//给所有io复用保留统一的接口
    virtual Timestamp poll(int timeoutMs,ChannelList * activecChannels)=0;//启动epollwait
    virtual void updateChannel(Channel *Channel) = 0;//epollctl
    virtual void removeChannel(Channel *channel) = 0;

poll,updateChannel,removeChannel设为纯虚函数不做处理,等子类对相应的函数进行细节处理。

Poller的核心poll(),当外界调用了poll这个方法该方法的底层其实调用的是epoll_wait函数。我们知道在muduo库当中每一个fd都对应着一个Channel,哈西表channels_可以让我们通过fd找到与之对应的channel。将来事件监听器监听到该fd上有事件发生,就可以通过哈西表将具体发生了什么事件写入到channel当中。poll当中的ativateChannels他的类型是(vector<Channel*>),当外界调用poll方法之后可以通过activateChannels拿到监听结果,也就是那些文件描述符就绪了,并调用Channel当中的对应事件的回调函数。

源码

//Poller.h
#pragma once

#include <vector>
#include <unordered_map>

#include "noncopyable.h"
#include "Timestamp.h"
#include "Channel.h"
class Channel;
class EventLoop;

class Poller : noncopyable {
public:
    using ChannelList = std::vector<Channel*>;
    Poller(EventLoop* loop) : loop_(loop) {};
    virtual ~Poller() = default;
    virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0;
    virtual void updateChannel(Channel* channel) = 0;
    virtual void removeChannel(Channel* channel) = 0;
    bool hasChannel(Channel* channel) const;
    static Poller* newDefaultPoller(EventLoop* loop);
protected:
    using ChannelMap = std::unordered_map<int, Channel*>;
    ChannelMap channels_;
private:

    EventLoop* loop_; 
};

//Poller.cc
#include "Poller.h"

bool Poller::hasChannel(Channel* channel) const {
    auto it = channels_.find(channel->fd());
    return it != channels_.end() && it->second == channel;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值