【源码讲解】sylar服务器框架----定时器模块

本模块实现了一个定时器,基于epoll实现。当epoll_wait函数退出时候,会检测是检测到了可读或可写的事件还是超时退出,若超时退出,则会执行注册的回调函数。本模块的定时器依赖于set。set内部实现了一个红黑树,当插入后会根据仿函数进行自排序。每次取出距离当前时间最近的一个超时节点。根据这个最近的时间来设置epoll_wait的超时时间。精度只能支持毫秒级,因为epoll_wait超时时间最小是毫秒。

本模块一共实现了两个类,一个是定时器模块,一个是定时器管理器模块。定时器模块是每一次定时时间,每个类有一个回调函数用于执行。(如果想要再同一时间点执行多个函数的话,就多用几个定时器就行)。定时器管理模块内容有一个set,管理定时器模块。TimerManager和Timer互相为对方的友元类。TimerManager是一个接口类,由io协程调度模块进行继承。

定时器模块:

构造函数:

构造函数共有两种,都是私有函数,只有在TimerManager中才能创建timer对象。第一种为四个参数,分别传入定时的时间,回调函数,是否循环调用以及定时器管理类的指针(非智能指针)。定时的时间为相对实践,在构造函数中,还需要加上当前时间,计算下次执行回调函数的时间,存入m_next中。第二种构造函数仅一个参数,传入下一次执行回调函数的时间。

仿函数:

判断两个定时器下一次执行回调函数时间的远近,若有一个参入作为参数的指针为空的话,那么他的时间就是最近的。

其他函数:

cancel函数用于去掉定时器。先上写锁,然后删掉定时器管理类的set函数中对应的timer。

refresh函数用于刷新设置定时器的执行时间。先上写锁。若set中没有此timer或者没有回调函数的话,则刷新失败,返回false。然后先从set中删掉此timer,然后重新设置下一次执行回调函数的时间,然后再加入到set中进行排序,然后返回true表明刷新成功。

reset函数用于重置定时器的时间,传入两个参数,第一个参数是定时器执行的间隔时间,第二个参数是是否从当前时间开始计算。若传入的定时的时间和原来的相同,且不需要从当前时间开始计算的话,直接返回。然后从set取出此timer并删除,若没有则返回false表示失败。若从当前时间开始计算,那么设置的m_next为当前时间加上定时的时间,若不是,则m_next的时间不变。然后修改定时的时间,并再次加入到set中。

定时器管理器模块

成员变量:

m_timers为一个set,用于存定时器,内部会自动根据仿函数返回的值将定时器根据下一次执行的时间,从小到大进行排序。

m_tickled用于判断是否有新的定时器插入到set中,并且执行的时间比原本最近执行的时间还要近,则设置为true。

m_previouseTime用于记录上一次执行的时间。

构造函数:

只有一个无参构造函数,初始化m_previouseTime(上次执行的时间)为当前时间。

addTimer函数:

addTimer函数用于添加新的定时器,首先向set中插入定时器。若插入之后,插入的timer成为了最近要执行的定时器,那么就将m_tickled设置为true,然后执行onTimerInsertedAtFront函数。

onTimerInsertedAtFront函数:

onTimerInsertedAtFront函数是一个纯虚函数,会在io协程调度模块中进行重写。

detectClockRollover函数:

detectClockRollover函数用于检测服务器的时间是否被调后了,传入当前时间,判断now_ms是不是小于m_previouseTime,如果是,则被调后了。

hasTimer函数:

判断set是否为空。

addConditionTimer函数:

这个函数用于添加条件定时器,共有四个参数,分别是定时的间隔时间,定时器执行的回调函数,一个weak智能指针作为条件,是否循环。经过一定的间隔时间后,判断weak指针是否为空来决定是否执行回调函数。

getNextTimer函数:

这个函数用于返回距离下一个最近的定时器还有多少毫秒。

listExpiredCb函数:

这个函数传入一个vector数组,数组内的成员是funtion,通过传入传出参数获取当前定时器管理器的全部回调函数。用于当定时器到时间的时候,收集全部需要执行的回调函数,因为同一时间需要执行的回调函数可能不止一个,所以需要传入传出一个vector数组。在io协程调度模块中,每当epoll_wait返回的时候都会执行这个函数。在listExpiredCb函数内部判断是否有回调函数需要执行,如果最近需要执行的定时器的到期时间比当前时间还要大的话,那么函数直接退出不执行。收集需要执行的回调函数的时候,首先从set中全部取出并且删除。然后根据是否设置m_recurring(循环定时器)来判断是否再加入到set中。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值