NS2的离散事件驱动原理(Scheduler, Handler, Event, Timer)

NS2是离散事件驱动的仿真机制,这一点文献到处都在讲但却始终没有讲到点子上。本文试图从几个NS2的基本类出发探究一下离散事件驱动究竟是怎么回事。
      首先是Scheduler,Handler和Event类的关系。
      在NS2中,事件(Event)是基本的调度单元,比如发送一个Packet、接收一个Packet等等。每个Event都有自己的处理工具,这个工具就是一个Handler类的对象handler_。Handler中仅包含一个函数,描述对Event的处理方法,即handle(Event *e)。
      给定一个事件,Scheduler将调用schedule(Handler* h, Event* e, double delay)函数,该函数设定Event的uid_,并设定用于处理该事件的Handler:e->handler_ = h,然后将该事件插入Scheduler维护的事件队列中。一般说来,处理事件的Handler都是产生该事件的实体本身,所以我们常常可以看到schedule函数在调用的时候*h用到this指针。
      NS2运行仿真时,Scheduler::run()函数不停地运行来处理队列中的事件,队列中的事件逐个dequeue()出来,随后运行Scheduler::dispatch(Event* p, double time)函数,将一个事件从队列中弹出来,调用它对应的Handler的handle()函数处理该它。
      这样就完成了一个事件从产生到排队到派出被处理的过程。

      接下来看一下TimerHandler的作用。
      计时器(Timer)是NS2仿真的关键手段,它用来设置一个未来的事件,在它到时后事件将被dispatch出来进行处理。Timer都是TimerHandler基类的派生类。TimerHandler与Scheduler交互的函数是sched(double delay),它调用Scheduler::schedule(Handler* h, Event* e, double delay)插入一个delay时间后的事件进入队列,Handler设置为TimerHandler本身(用this)。
      delay时间到了后,Scheduler会从事件队列中dequeue出该事件,调用其处理函数,也就是TimerHandler::handle() 。而handle()除了做一些计时器的状态设定工作外,核心的处理由虚函数expire(Event* e)来做。由C++的动态特性不难理解,expire()将在各种自定义的Timer(也就是TimerHandler的派生类)中进行重写,实现各Timer的不同处理方法。

      看一个具体的例子
      以NIST Wimax模块中的DlTimer为例,该Timer用于触发一个下行帧的生成:
class DlTimer : public TimerHandler {
public:
DlTimer(Mac802_16 *m) : TimerHandler() {m_=m;}

void    expire(Event *e);
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) {
     (void)Scheduler::instance().schedule(this, &event_, 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完成一个调度工作的全过程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NS2网络模拟器的原理和应用 内容简介 本书要介绍的是由UC Berkeley设计、起初由VINT Project团队维护的一套网络仿真软件NS2(Network Simulator-Version 2,简称NS2)。NS2是一个面向对象的、用离散事件驱动的、利用C++语言和OTcl语言编写的网络模拟器,主要是用于局域网和广域网的网络模拟和协议算法模拟。 利用NS2,可以很方便地模拟一个算法。首先需要建立自己的仿真环境、可能的网络状况,然后设定相关的参数、通讯协议等,交给NS2去执行,得到一个输出文件,再利用一些辅助软件如NAM,XGraph,Gnuplot,Perl等做进一步的分析。比起传统的做法,NS2要容易得多,也节省了不少经费和时间。这就是为什么要用NS2来做模拟的原因! 目录 第一部分 NS2基础  第1章 NS2概述   1.1  NS2简介   1.2  NS2的基本结构   1.3  NS2中C++和0Tcl的关系   1.4 使用NS2的流程   1.5 模拟结果的分析   1.6  NS2中对象和各种协议的对应关系  第2章 NS2安装   2.1 在Unix平台下安装NS2   2.2 在Win9X/2000/XP环境下安装NS2  第3章 Tcl语法   3.1 Tcl语言简介   3.2 变量(Variable)   3.3 表达式(Expression)   3.4 命令替换(Command Substitution)   3.5 流程控制(Control Flow)   3.6 过程(Procedure)   3.7 数组(Array)   3.8 类(Class)   3.9 字符串(String)   3.10 输出(Output)   3.11 列表(List)   3.12 Tcl内置命令  第4章 NS2语法   4.1 一个简单的例子   4.2 基本语法 第二部分 NS2结果分析  第5章 跟踪文件out.tr  第6章 动画演示工具NAM 6.1  NAM的命令行选项 6.2 用户接口  第7章 分析工具Awk 7.1  Awk简介 7.2  Awk的运行过程  第8章 绘图工具XGraph和Gnuplot 8.l XGraph简介 8.2 Gnuplot简介  第9章 实例 9.1 用Awk分析 9.2 用XGrapb和Gnuplot绘图 第三部分 NS2对象  第10章 模拟器(Simulator) 10.1 类Simulator 10.2  Simulator初始化 10.3 调度器和事件 10.4 其他方法 10.5 命令一览  第11章 节点和包(Node and Packet)   11.1 节点的基本元素   11.2 节点的设置方法   11.3 节电设置接口   11.4 分类器   11.5 复制器   11.6 路由模块和分类器的组织   11.7 命令一览  …… 第四部分 NS2解释器接口 第五部分 NS2扩展 第六部分 实例 参考文献
If you're encountering the error message "Event Scheduler: Unable to schedule event" in MySQL, there could be a few possible reasons for this issue. Here are some troubleshooting steps you can try: 1. Check if the event scheduler is enabled: Execute the following query to verify if the event scheduler is enabled: ```sql SHOW VARIABLES LIKE 'event_scheduler'; ``` If the value is set to "OFF", you can enable it by setting the `event_scheduler` variable to "ON" in your MySQL configuration file (`my.cnf` or `my.ini`). Alternatively, you can enable it dynamically by executing the following query: ```sql SET GLOBAL event_scheduler = ON; ``` 2. Verify the syntax and permissions: Ensure that the syntax of your event creation statement is correct and that you have the necessary privileges to create and schedule events. Make sure you are using a user account with the `EVENT` privilege. 3. Check event-related variables: Verify if the `event_scheduler` variable is set to "ON" and that the global `max_allowed_packet` variable has a sufficient value to accommodate your event. 4. Investigate other errors: If there are any other error messages or warnings displayed when creating or scheduling the event, carefully review them for any additional clues. 5. Restart MySQL service: In some cases, restarting the MySQL service can resolve issues related to the event scheduler. If none of these steps resolve your issue, please provide more specific details about your event creation statement and any other relevant error messages that you're encountering.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值