ceph存储 ceph集群定时器safetimer的实现

定时器的作用是在指定的时间执行指定的动作。SafeTimer通过multimap数据结构维护定时项,定时项是时间和事件的Pair,定时项在map中按照定时时间从小到大排列。此外,SafeTimer使用一个线程来轮询定时项,当到达定时项指定的时间时执行对应的事件。下面代码是这个线程的入口函数:

voidSafeTimer::timer_thread()

{

   lock.Lock();

   while (!stopping) {

      utime_t now = ceph_clock_now(cct); /// 获取当前时间

   

      while(!schedule.empty()) {

       scheduled_map_t::iterator p = schedule.begin();

 

        /// 还没达到指定的定时时间

          /// 因为schedule中的定时项是已经排好顺序的,第1个元素就是最先要处理的事件,所以只要检查第1个元素就可以了

        if (p->first > now) {

              break;

        }

 

        /// 处理指定的事件

        Context *callback =p->second;

        events.erase(callback);

        schedule.erase(p);

       

        if (!safe_callbacks){

           lock.Unlock();

        }

  

          /// 处理事件时,解锁。因为处理事件不会修改定时器本身的数据

        callback->complete(0);

        if (!safe_callbacks){

              lock.Lock();

        }

      }

 

      /// 当使用者向schedule插入新的定时项时,如果新的定时项的时间是最早的,那么它会唤醒该线程

      if(schedule.empty()) {

            cond.Wait(lock);

      } else {

            /// 等待指定的时间

            cond.WaitUntil(lock, schedule.begin()->first);

        }

   }

  lock.Unlock();

}

 

定时器实现考虑以下几个因素:1) 定时项按照从早到晚排序,通过std::multimap实现;2) 修改定时器相关的数据时加锁,执行定时动作前解锁。这样就不会阻塞其它线程对定时器的操作,例如添加、删除定时项;3) 当新加入的定时项位于队列头部时,唤醒定时线程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值