norbert_jxl 发表于 2011-12-21 08:43

NS2中的定时器

首先需要知道的是定时器(Timer)既可以在C++中实现也可以在Otcl中实现。在C++中,各种定时器都是基于抽象基类TimerHandler
的,而其又是由Handler继承来的,而且定时器经常用于Agent对象中,当然也可以用在其他对象中,这里主要说在Agent对象中的使用方法。
<div>&nbsp;&nbsp;&nbsp; &nbsp; 列举几个比较重要的函数和参数:</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;sched():设定定时器在delay秒后超时,此时定时器必须处在TIMER_IDLE状态。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;resched():重新设定定时器的超时时间,在调用resched(()函数时,定时器可以处于TIMER_PENDING状态。</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp; cancel():取消定时器,调用cancel()函数时定时器必须处于TIMER_PENDING状态。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;status():返回定时器的当前状态,状态值可能是TIMER_IDLE,TIMER_PENDING,TIMER_HANDLE.</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TIMER_IDLE:是对象刚刚被初始化或者被取消之后的状态。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TIMER_PENDING:是当调度一个时间之后处于的状态。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;TIMER_HANDLE:是当定时器时间到转而去执行一个特定任务时的状态。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;expire():是纯虚函数,必须由派生类给出,即用户自行定义实现其功能。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;
handle():处理一个事件,当定时器超时后,Scheduler对象会调用定时器的handle()函数,并把event_()作为参数,此时定时
器的状态不能为TIMER_PENDING.handle()函数会调用expire()函数,并设定定时器的status_。</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp; int status_:保存当前定时器的状态。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; Eventevent:当定时器超时后需要处理的事件。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; 下面举个简单的例子:</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;<font color="#ff0000">class Rumorrouting_BroadTimer : public TimerHandler {</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; public:</font></div>
<div><font color="#ff0000">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Rumorrouting_BroadTimer(Rumorrouting* agent) :TimerHandler() {</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; agent_ = agent;</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; protected:</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Rumorrouting* agent_;</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;virtual void expire(Event* e);</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; };</font></div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; 下面是Rumorrouting类的定义:</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<font color="#ff0000">class Rumorrouting : public Agent {</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;friend class Rumorrouting_BroadTimer;</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;……</font></div>
<div><font color="#ff0000">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Rumorrouting_BroadTimer broad_timer_;</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;……</font></div>
<div><font color="#ff0000">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;void reset_rumorrouting_broad_timer();</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;……</font></div>
<div><font color="#ff0000">&nbsp;&nbsp;&nbsp; &nbsp; }</font></div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; 再看Rumorrouting的构造函数:</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;<font color="#ff0000">Rumorrouting::Rumorrouting(nsaddr_t id) :Agent(PT_RUMORROUTING), broad_timer_(this), ……</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; {</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;……</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; }</font></div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;我们发现对定时器对象broad_timer_的初始化是用this指针,而从最上面定时器类的定义中我们发现this指针赋值给了agent_变量。</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp; 接着看:</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;<font color="#ff0000">&nbsp;void&nbsp;Rumorrouting_BroadTimer::expire(Event*e) {</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;agent_-&gt;send_broad_pkt();</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;agent_-&gt;reset_rumorrouting_broad_timer();</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; }</font></div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;我们发现当超时以后会重传,然后再调用Rumorrouting的reset_rumorrouting_broad_timer()函数。</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp; 我们再来看一下Rumorrouting的reset_rumorrouting_broad_timer()函数:</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;<font color="#ff0000">&nbsp;Rumorrouting::reset_rumorrouting_broad_timer(){</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if(broadTimes&lt;BROAD_HELLO_MAX)</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</font></div>
<div><font color="#ff0000">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; broad_timer_.resched((double)0.5);</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; broadTimes++;</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</font></div>
<div><font color="#ff0000">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; broad_timer_.resched((double)600000.0);</font></div>
<div><font color="#ff0000">&nbsp;&nbsp; &nbsp; &nbsp; }</font></div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;这里便用到了broad_timer_定时器对象,并且利用resched()函数重新设定了超时时间。</div>
&nbsp;&nbsp; &nbsp; &nbsp;OK了,对TimerHandler的使用应该比较清晰了~
页: [1]
查看完整版本: NS2中的定时器