muduo库的学习3---loop基本设计---总论

来源:互联网 发布:淘宝上的6s官换机真相 编辑:程序博客网 时间:2024/05/21 11:32

这里所涉及的文件包括

(1)loop用的:Callbacks,Poller,EventLoop,EventLoopThread,EventLoopThreadPool

(2)IO用的:Channel

(3)Timer用的:Timer,TimerQueue,TimerId


1.与Libev对比

可以用于libev的对比来很好滴表达

(1)Poller+EventLoop实现了libev的loop循环

(2)Channel就是libev的io_watcher

(3)TimerQueue就是libev的timer_watcher(但是注意muduo中有N多个定时事件,也只是有一个timer_watcher)

这样对应以后,功能也就是一目了然。


2.程序的组织


如图所示,一个线程持有一个loop

一个loop通过一个poller来实现IO multiplexing

有前面可知,Channel的作用相当于watcher,IO事件以及Timer事件都是通过文件描述符,注册一个Channel来操作的。


注意:

(1)各个fd

一个channel/watcher只能对应一个fd。

listenfd只有一个用于服务器接受连接请求,并为新的connection建立监听

connfd可以有若干个,所以就会建立对应那么多个channel

timerfd,这里TimerQueue里面可以有很多个timer,每一个timer代表一个时间事件。

但是整个TimerQueue在Poller中只对应一个channel。


(2)详细解释timer相关

有关对于时间处理的简单示例代码可以参考muduo/net/tests/Channel_test.cc


IO的fd都是一个fd对应一个channel,每个channel的callback都是对应于那个时间的处理

而包含有许多timer的TimerQueue只有一个fd,当在这个fd的事件到达,会调用TimerQueue::handleRead作为CallBack。

在handleRead中,再将TimerQueue中的这个时候超时的所有的timer的callback一一调用。


①代表整个TimerQueue的timerfd是在构造的时候调用timerfd_create创建的

并且还要通过用这个timerfd创建一个Channel,并且将这个channel设置为关注read事件,并加入poller的监听队列。

②目前的TimerQueue是空的,可以往里面加入timer(timer由when,cb组成,表示用户关心的一个时间发生的事件,以及发生后的callback)。

调用的顺序为add_timer----->addTimerInLoop-------->insert------------>判断是否调用resetTimerfd

这里的insert就是实际将timer插入底层数据结构的函数

关键就是这里的判断,它是判断当前新插入的这个timer是否比已经在队列中的所有timer的when的最前面(即?when_now<when_min)。

如果是就通过resetTimerfd在底层调用timerfd_settime,而这个函数的功能就是设定代表整个TimerQueue的channel关注的那个事件准备就绪的条件。


说穿了就是在用户所有关心的时间事件里面,将最先发生的那个作为Poller通知timerchannel事件发生(timerfd变为可读)的标志,

当定时发生,callback就调用handleRead。

这个handleRead再反过来调用这个时候到时的各个Timer的各自的callback。


3.类的数据成员包含关系

为了进行逻辑判断,一个类里面本身有很多数据成员,但是我在这里忽略一些循环变量,用于指示的布尔变量。

只关心muduo库的类的对象作为数据成员

(1)EventLoop

①poller

②timerQueue

③wakeupChannel

④activeChannels(vector)

(2)Poller

①ownerLoop

②channels(map<int, Channel>即map<fd, Channel>)

③pollfds(vector<struct pollfd> stated in pollpoller.h)

(3)Channel

①loop

②fd,events,revents

③read,write,close,error四种Callback(boost::function<>)

(4)TimerQueue

①loop

②timerfd

③timerfdChannel

④timers(set<pair<Timerstamp, Timer*>>)

(5)Timer

①callback(boost::function<>  defined in Callbacks.h)

②expiration(Timerstamp)

③interval(double)






0 0
原创粉丝点击