NS2是离散事件驱动的仿真机制,这一点文献到处都在讲但却始终没有讲到点子上。本文试图从几个NS2的基本类出发探究一下离散事件驱动究竟是怎么回事。
class DlTimer : public TimerHandler { public: DlTimer(Mac802_16 *m) : TimerHandler() {m_=m;} void private: Mac802_16 *m_; }; 在使用该Timer的MAC实体中,Mac802_16BS::init()函数中打开了该Timer: double stime = getFrameDuration () + Random::uniform(0, getFrameDuration ()); dl_timer_->sched (stime); 这个计时器被定时在stime后触发事件。那么Scheduler在到时后会做些什么呢?由上面知道,将会由schedule()函数会调用该事件的Handler处理该事件。这个事件的Handler是什么呢?查看sched()的代码可以溯源到一个内联函数: inline void _sched(double delay) { } 该函数设定event_的Handler为this,也就是调用schedule()的对象,而这个对象回溯回去正是dl_timer_!于是我们知道,该定时器到时后将会调用dl_timer_的handle()函数做事情,而DlTimer又是直接继承了TimerHandler的handle()函数,而TimerHandler::handle()函数是靠虚函数expire(Event* e)做事的。在DlTimer继承TimerHandler时正好重写了expire函数: void DlTimer::expire (Event *e) { m_->start_dlsubframe(); } 现在事情就变得明朗了,dl_timer_到时后Scheduler触发了一个事件,这个事件引发的是MAC802_16类的start_dlsubframe()动作,这个函数正是“开始下行子帧”。这样就完成了用一个Timer完成一个调度工作的全过程。 |