RPC中定时器制作思路
定时器设计
time_event
time_event 类用来封装定时时间,内部需要包含一个任务执行时间,是否重复标记、是否取消标记,对于重复任务,还需要一个重复间隔时间。以及一个回调函数,用来执行任务到期后需要执行的动作。
构造函数传入这些参数,即1:到期执行的任务函数 2:重复间隔时间 3:首次执行的时间戳。
timer
timer是具体的定时器类,内部包含多个time_event,由于多个time_event可能有相同的执行时间,可以采用std::multimap存储这些time_event, 其中key为执行时间戳,value为time_event.
需要提供注册time_event的接口和取消time_event的接口。
包含一个time_fd(linux系统原生),可挂载在epoll_wait上。
需要设计一个OnTime接口,用来做epoll_wait返回时的回调函数,在OnTime回调函数中,去执行到期的time_event任务。
执行完成后,需要重置到期时间,以time_events中第一个到期的时间设置成timer_fd的时间,即下次epoll_wait返回,调用OnTime的时间。之所以用第一个,是因为用std::multimap存储的这些time_event, std::multimap按key大小升序排序,第一个就是最近要到期的时间。
OnTime执行时,需要将已经执行完的任务从map中删除,对于重复任务,需要重新计算其到期时间,然后再添加到map中。
EventLoop启动时建立一个定时器,将其挂载上,后续使用者只需要创建自己的time_event类型,在其中添加自己的任务即可(EventLoop需要提供添加接口)
这里有两次回调函数
1: timer中的OnTime回调函数,是epoll_wait返回时,调用的timer回调函数(epoll_wait中当然只会注册一个定时器,不会去注册每一个定时任务)
2:time_event中的回调函数,这个回调函数是使用者注册的,即定时任务的具体内容,由OnTime调用这些业务回调函数。
可参考代码:
https://github.com/LIMengjie1/rocketrpc/tree/main/rocket/net
其中的timer.cpp 和timer_event.cpp 即按上述思路设计