简介
定时器功能由TimerId,Timer,TimerQueue实现,用户只能看到TimerId
TimerQueue只暴露两个接口addTimer和cancel,addTimer供eventloop使用,会包装成runat,runafter,runevery
实现
- TimerQueue需要快速找到已经到期的Timer,muduo使用std::map将Timer按到期时间先后排序,操作复杂度为O(logN),由于两个Timer到期时间可能相同,因此key设置为<Timestamp,Timer*>
- TimerQueue的成员函数只归所属IO线程调用,因此不必加锁
- getExpired会从TimerList中移除到期的Timer,并通过vector返回(编译器会实施RVO优化,不必担心性能)。
eventloop调用
runat,runafer,runevery都调用了addTimer,这三个函数应该运行跨线程,比如在某个IO线程超时回调。muduo不使用加锁解决,而使用runInloop把TimerQueue操作转移到IO线程进行
runInloop在IO线程执行某个用户任务回调。如果当前IO线程调用这个函数,回调会同步进行。如果用户在其他线程调用runinloop,cb会加入队列,io线程会被唤醒调用这个functor
有了这个功能,就可以轻易在线程间调配任务。由于IO线程平时阻塞在loop的poll调用,所以为了能立即执行用户回调,需要设法唤醒它。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/288253.html