muduo 14 Poller抽象层代码

目录

Poller扮演角色:

Poller成员变量:

Poller成员函数:

Poller.h

Poller.cc        


Poller扮演角色:

        TCP server里边儿非常重要的一个东西呢,就是event loop事件循环,一个事件循环对应一个线程,一个线程对应一个事件循环。

        一个事件循环就是event loop里边对应了一个poller跟一堆的channel,现在来实现poller。

        muduo的Eventloop在使用IO复用的时候,并没有直接指定epoll,muduo对象外提供IO复用的能力有2个,一个是poll,一个是epoll,是从抽象层面使用抽象基类Poller,到时候引用不同的派生类,调用同名覆盖方法,就可以非常方便的去扩展不同的IO复用能力。

Poller成员变量:

①: 存放所有Channel的容器,使用一个无序map;

②: 一个当前poller所在loop的指针。

Poller成员函数:

①:声明ChannelList链表容器,用于存放感兴趣的事件;

②:构造函数:

析构函数:要定义成虚函数,因为要做基类,后面EpollPoller将由它来派生

③:一系列的纯虚函数:

        poll相当于启动了epoll_wait;updateChannel相当于启动了epoll_ctrl;removeChannel将fd所感兴趣的事件delete掉。

具体实现将在EpollPoller中描述。

④:判断传入参数的channel是否在当前poller的ChannelMap容器中

 ⑤:根据全局变量判断生成那种类型的IO复用poll或者epoll

Poller.h

#pragma once

#include "noncopyable.h"
#include "Timestamp.h"

#include <vector>
#include <unordered_map>

class Channel;//只用到指针类型 
class EventLoop;//只用到指针类型 

//muduo库中多路事件分发器的核心IO复用模块
class Poller : noncopyable
{
public:
    using ChannelList = std::vector<Channel*>;

    Poller(EventLoop *loop);
    virtual ~Poller() = default;//虚析构函数 

    //给所有IO复用保留统一的接口 纯虚函数
    virtual Timestamp poll(int timeoutMs, ChannelList *activeChannels) = 0;//相当于启动了epoll_wait 
    virtual void updateChannel(Channel *channel) = 0;//相当于启动了epoll_ctrl 
    virtual void removeChannel(Channel *channel) = 0;//fd所感兴趣的事件delete掉 
    
    //判断参数channel是否在当前Poller当中
    bool hasChannel(Channel *channel) const;

    //EventLoop可以通过该接口获取默认的IO复用的具体实现 
    static Poller* newDefaultPoller(EventLoop *loop);

protected:
    //map的key:sockfd  value:sockfd所属的channel通道类型
    using ChannelMap = std::unordered_map<int, Channel*>;
    ChannelMap channels_;

private:
    EventLoop *ownerLoop_;//定义Poller所属的事件循环EventLoop
};

1. 因为muduo对外提供IO复用接口有两个一个是poll,一个是epoll;

2. 在eventloop中不可能直接使用poll或者epoll,也没有指定。

3. Poller类定义成抽象类,通过引用不同的派生类对象,可以调用同名覆盖方法,就可以非常方便的去扩展不同的IO复用能力。

可以通过newDefaultPoller(EventLoop *loop)函数实现IO复用类型

//公共源文件
#include "Poller.h"
#include <stdlib.h>


Poller* Poller::newDefaultPoller(EventLoop *loop)
{
    if(::getenv("MUDUO_USE_POLL"))
    {
        return nullptr;  //生成一个poll实例
    }else{
        return nullptr;  //生成一个epoll实例
    }
}

通过环境变量控制,设置IO复用接口类型

        poller成员变量包含了一个map里面存放多个channel。 

protected:
    //map的key:sockfd  value:sockfd所属的channel通道类型
    using ChannelMap = std::unordered_map<int, Channel*>;
    ChannelMap channels_;

private:
    EventLoop *ownerLoop_;//定义Poller所属的事件循环EventLoop

Poller.cc        

#include "Poller.h"
#include "Channel.h"

Poller::Poller(EventLoop *loop)
    : ownerLoop_(loop)
{

}

bool Poller::hasChannel(Channel *channel) const
{
    auto it = channels_.find(channel->fd());
    //保证这个channel在poller的map里面
    return it != channels_.end() && it -> second == channel;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值