ceph Timer源码分析

ceph Timer源码分析

ceph定时器主要用来实现某些定时任务,比如osd之间的心跳,monitor之间的心跳等.
源文件:

  1. src/common/timer.h
  2. src/common/timer.cc
  3. src/include/Context.h

定时器事件或者任务

ceph中的事件都继承自Context类,并且实现自己的事件处理方法finish().例如基于定时器的心跳机制就是在finish中每隔一段时间发送一个ping请求.

class Context {
  Context(const Context& other);
  const Context& operator=(const Context& other);
 protected:
 // finishe: 事件的处理方法
  virtual void finish(int r) = 0;
 public:
  Context() {}
  virtual ~Context() {}       // we want a virtual destructor!!!
  virtual void complete(int r) {
    finish(r);
    delete this;
  }
};

定时器线程

定时器线程用于执行定时器任务,具体的任务处理方法由SafeTimer类的timer_thread()定义.

class SafeTimerThread : public Thread {
  SafeTimer *parent;
public:
  explicit SafeTimerThread(SafeTimer *s) : parent(s) {}
  void *entry() {
    parent->timer_thread();
    return NULL;
  }
};

定时器

定时器由定时器线程和定时器任务组成,由定时器线程周期的处理定时器任务.

class SafeTimer:
主要数据成员:
	CephContext *cct
	Mutex &lock
	Cond cond
	bool safe_callbacks
	SafeTimerThread *thread 定时器线程
	// schedule和events都表示定时器任务集,
	// 前者采取时间到事件的映射方式,主要用于定时器线程按时间执行定时器任务.
	// 后都采用事件到迭代器的映射方法,主要用于主线程按事件名取消事件.
	multimap<utime_t, Context*> schedule
	map<Context*, multimap<utime_t, Context *>::iterator> events
	bool stopping 定时器线程的终止状态标志
主要成员函数:
	init():
		thread = new SafeTimerThread(this) 新建定时器线程
		thread->create("safe_timer") 启动定时器线程
	timer_thread(): 定时器线程的执行函数
		确定定时器线程处于执行状态,即stopping为false.
		当事件集schedule不为空时,循环检查事件是否期执行.
		事件在schedule中是按照时间升序排列的.
		如果第一个事件没有到时间,后面的事件就不用检查了,直接终止循环,然后等待.
		如果第一个事件到定时时间,就调用它的finish()进行处理
		处理完当前事件后,等待直到下一个事件的时间.
	shutdown():
		取消全部定时器事件
		销毁定时器线程thread
	add_event_after(double seconds, Context *callback):
		基于相对时间when增加定时器事件
	add_event_at(utime_t when, Context *callback):
		基于绝对时间when增加定时器事件
	cancel_event(Context *callback):
		根据事件名取消定时器事件
	cancel_all_event():
		取消全部定时器事件

question:
定时器线程一个时刻只能处理一个事件,那如果有两个事件时间相同,怎么处理?
理论上一个线程不可能同时执行两个事件,问题的关键在于timer_thread()函数的在执行:定时器事件是按执行时间排序的,因此定时器线程执行事件的过程是,执行一个事件,等待一段时间,执行下一个事件…因此如果两个事件的执行时间相同,那么定时器线程不等待直接执行该事件,由于每个事件的执行时间很短,因此可以近似认为两个事件是同时执行的.这里其实用到了一个小技巧:pthread_cond_timedwait(cond, mutex, time),time是绝对时间,如果time值大于当前时间now,那么线程等待now-time,但如果time小于等于now,那么线程不等待直接执行.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值