NS3 Events和Simulator内容翻译

以下内容是NS3手册翻译。

1.4 Events and Simulator

ns-3是一个离散事件网络仿真器。从概念上讲,仿真器跟踪了大量的在指定的仿真时间内按计划执行的事件。仿真器的工作就是以顺序的时间序列执行事件。一旦一个事件执行完毕,仿真器将转到执行下一个事件(或者将退出如果在事件队列中没有更多的事件)。例如,如果一个事件在100秒的仿真时间被执行了,下一个事件不会执行止到到200秒,仿真器会从100秒跳到200秒(仿真时间)执行下一个事件。也就是离散事件仿真器的意义。
为按照上面执行,仿真器需要一些事情:

1.仿真器对象可以访问存放事件的事件队列,并可以管理事件的执行。
2.调度器负责从对列中插入和删除事件。
3.一种表示仿真时间的方式
4.事件自身

手册的这一章节描述了这些基本的对象(simulator,scheduler,time,event)和如何使用它们。

1.4.1 Event
待完成

1.4.2 Simulator

simulator类是访问事件调度设施的公共入口点。一旦一对事件已经计划启动仿真,用户可以通过输入模拟器主循环来执行它们(调用Simulator::Run)。一旦主循环开始运行,它将会按着顺序从最老的事件到最近添加的事件执行所有计划的事件,止到剩下没有更多的事件或者调用Simulator::Stop。

为了调度被仿真器主循环执行的事件,Simulator类提供了Simulator::Schedule函数组。

1.不同签名的处理事件的处理器

void handler (int arg0, int arg1)
{
    std::cout << "handler called with argument arg0=" << arg0 << " and
    arg1=" << arg1 << std::endl;
}
Simulator::Schedule(Seconds(10), &handler, 10, 5);

这些代码的输出:

handler called with argument arg0=10 and arg1=5

自然,这些C++模板也可透明的处理C++对象的成员方法:
To be completed: member method example
注意:

• 只有少于5个参数的情况下,ns-3 Schedule methods自动组织调度函数和方法。如果你需要它们支持更多的参数,请提交bug报告。
• 读者与术语“fully-bound functor”类似将组织Simulator::Schedule方法作为一个自动构造这些对象的方法。  

2.通用的调度操作

Simulator API被设计来简单的完成调度大部分事件。它提供了三个变种来完成这些(从使用最多到使用最少进行排序):

• Schedule methods允许你在当前仿真时间和目标事件的过期时间之间,通过在未来内提供一个延时来调度一个事件。
• ScheduleNow方法允许你在当前仿真时间调度一个事件:它们将会在当前事件执行完成之后执行,但是在下一个事件仿真时间被改变前执行。
• ScheduleDestroy方法允许你设置仿真器的关闭过程的一个钩子来清理仿真资源:当用户调用Simulator::Destroy方法,每一次“destroy”事件就会被执行。

3.保存仿真上下文

有两个调度事件的基本方法,带上下文和不带上下文。这是什么意思呢?

Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj);
vs.
Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj);

投入了很大时间和精力来开发或者使用一个不平凡的仿真模型的读者会知道ns-3日志框架的价值,使得debug的简单和复杂的仿真一样。重要的特性之一就是通过提供日志框架自动展现与当前运行的事件相关联的网络节点id。

当前执行的网络节点的node id事实上已被Simulator追踪。它可以使用Simulator::GetContext方法访问,该方法返回相关联的和存储在当前正在执行的事件的“context”(一个32位整数)。在某些罕见的情况下,当一个事件没有与一个具体的网络节点关联,它的“context”被设置成0xffffffff。

为了给每一个事件关联一个context,Schedule和ScheduleNow方法自动重用当前正在执行事件的context作为计划稍候执行的事件的context。

在某些情况下,特别是仿真一个包从一个节点传输到另一个节点的情况,这种行为是不好的,由于接收事件的期望的context是接收节点的,而不是发送节点的。为了避免这个问题,Simulator类提供了一个具体的调度方法:ScheduleWithContext,它允许提供关联到接收事件的接收节点一个明确的node id。

XXX:code example

在某些极其罕见的情况,开发者可能需要改变或者理解第一个事件的“context”(也就是node id)是如何与它关联的节点(node)进行设置的。这是通过NodeList类完成的:无论何时一个新的node节点被创建了,NodeList类使用ScheduleWithContext来为这个node节点调度一个“initialize”初始化事件。因此这个“initialize”事件使用设置的context,也就是node id来进行执行,并可以使用调度方法的正常的重载(注:这里的意思应该是能够调用调度方法的不同的重载)。它调用Node::Initialize方法,这个方法通过为关联到这个node节点的每个对象调用DoInitialize方法来传播“initialize”事件。这个DoInitialize方法在一些对象中被重载了(特别是在Application基类中),这将调度一些事件(特别是Application::StartApplication),这些事件反过来会调度流量产生事件,而流量产生事件反过来会调度网络层事件(network-level events)。

注意:

 •  Users need to be careful to propagate DoInitialize methods 
    across objects by calling Initialize explicitely on their member objects
 •  The context id associated with each ScheduleWithContext 
    method has other uses beyond logging: it is used by an experimental 
    branch of ns-3 to perform parallel simulation on multicore systems using multithreading.

Simulator::函数不知道context是什么:它们仅仅确保当相应的事件使用Simulator::GetContext执行的时候,你使用ScheduleWithContext指定的context是可用的。

根据在Simulator::上实现的模型解释了这个context值。在ns-3中,网络模型解释context作为产生事件的node节点的节点id(node id)。这就是为什么在ns3::Channel子类中调用ScheduleWithContext是重要的,以因为从节点i到节点j,我们产生了一个事件,并且我们想要确保运行在节点j上的事件具有正确的context。

你可能感兴趣的:(NS3 Events和Simulator内容翻译)