《Linux多线程服务器端编程》8.0-8.3节读书笔记(Muduo库Reactor的关键结构)

EventLoop类

对于一个网络库而言,该类是整个程序运行起来的核心,一个EventLoop对象对应于一个循环,每个EventLoop对象只能由一个线程所拥有。当该对象被创建之后,调用其loop()接口即可使整个程序跑起来。

该对象中保存了其所属的线程的线程ID,在运行EventLoop对象所提供的接口时,可以判断当前运行此对象的线程是否为该对象所属的线程。理论上了为了防止多线程下的竞争问题,一般EventLoop对象只能在其所属的IO线程中调用。

除此之外,该类还拥有一个Poller类对象和一个ChannelList对象(用于保存Poller对象返回的所有的活跃fd)。

Channel class类

每当创建了一个fd时则都会对应一个Channel,该对象自始至终都只负责一个文件描述符fd的IO事件分发。同时每个Channel都只会对应一个EventLoop对象。

Channel对象中包括了该fd所关心的IO事件(POLLIN或者POLLOUT等),以及目前该Channel的活动事件。同时该对象提供接口

enableReading()等来改变该fd所关心的IO事件,并向EventLoop注册或者修改该fd。同时提供接口setReadCallback等来设置该fd当发生相应的事件时的回调函数。同时也提供接口handleEvent来处理当Poller返回时的相应的某个fd的IO事件。

Poller class类

Poller 是对IO多路复用的封装,在Muduo库中即poll或者epoll两种。Poller是EventLoop对象的成员,其生命周期与EventLoop对象相同。

在Poller类对象中保存有channel list,用户保存当前注册到Poller中的所有channel,同时Poller提供接口updateChannel来进行注册新的或者修改fd,而对于Poller而言核心操作即为Poller对象所提供的接口poll()

当接受到连接之后的运行流程

在EventLoop中调用loop接口,开始整个系统的运行。通过Poller对象的poll接口提供IO多路复用功能,当epoll_wait或者poll返回后,由Poller对象的fillActiveChannels接口将所有活动fd(以Channel的形式)全部提取出来,并存入ChannelList对象中,然后依次遍历该list,对于遍历到的每一个Channel,依次调用该Channel对象所提供的handleEvent函数来处理当前的的IO事件(handleEvent会根据该channel对象当前所发生的IO事件来调用其所注册的相应的函数来处理此IO事件)

而注册或者修改新连接(修改其所关注的IO事件)是通过Channel对象所提供的enablexxx接口来完成,该接口会调用其所属loop的updateChannel函数来处理,而最终是通过该函数调用该loop所拥有的Poller的updateChannel接口来完成注册或者修改。

发布了23 篇原创文章 · 获赞 4 · 访问量 2141

猜你喜欢

转载自blog.csdn.net/hdadiao/article/details/88416861