您的位置:首页 > Web前端

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

2014-12-17 09:56 337 查看
定时器的作用是在指定的时间执行指定的动作。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) 当新加入的定时项位于队列头部时,唤醒定时线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: