PeerSim之我分析事件机制

来源:互联网 发布:MOC Linux 编辑:程序博客网 时间:2024/06/03 19:39

进入main函数:

初始操作跟循环驱动差别不大,判断出事件机制后,进入nextExperiment()方法:

(1)            初始操作

建立堆栈heap,其中主要存有时间数组times,事件数组events,节点数组nodes,协议号数组pids,Event类型(priorityQ.Event)的ev。另外从配置文件中读取相关参数,如endtime,logtime,size之类的。

(2)            调用network.reset()设置网络

设置网络大小节点数组,根据原型节点(对于GeneralNode,其中包含节点protocol数组,index,ID等)来初始化网络中所有节点。节点中的Protocol[]保存协议书族实例。

(3)            runInitializers()(运行时初始化,即调用私有静态成员函数)。

读取配置文件,根据init关键字获取初始化器的对象实例数组(构建出WireKOut对象,CDScheduler 对象和LinearDistribution对象)。获取初始化器对象后再按照顺序一个个调用这些初始化器的execute方法。

1       dynamics.WirekOut类:跟循环驱动一样。

2     edsim.CDScheduler类:

作用:仅初始化时调用一次,这里节点实现几个CDProtocl接口的协议,就相应新建几个NextCycleEvent事件。最后在该初始化器执行execute()方法时,每个节点将相应个数的NextCycleEvent事件加入堆中,改变的只是时间,其出堆执行的时间的设置是从Scheduler对象的step数值里随机产生一值。

注:入堆的是NextCycleEvent对象而非协议,而实现CDProtocol接口的协议的执行由NextCycleEvent对象控制。

在获取类实例时,将先执行CDScheduler类的static代码块,主要初始化Scheduler类型的sch数组(将CDProtocol类型的协议赋值)。CDScheduler此类构造函数实现:主要是存NextCycleEvent类型对象(该NCE对象的构造函数什么也不做)的数组,有几个实现CDProtocol的接口协议,就有几个Scheduler,因而也就创建有几个NextCycleEvent类型对象。

由配置文件:init.sch.protocol avg,其负责调度AvergeED。

CDScheduler执行execute()方法,只在初始化时调用一次。主要用来将实现CDProtocol接口的基于循环机制的协议可以在事件机制中运行:每个节点将自身所有实现的CDProtocol协议的pid以及相应的NextCycleEvent和下次调用的时间加入中。

注意:此堆是小堆,加入或者删除之后都要按照执行时间重新进行排序。

3       vector.LinearDistributionextends vectControl extends getter/setter:

根据配置文件init.vals.protocol avg,该初始化器主要初始化AvergeED协议(该协议实现了CDProtocol,EDProtocol接口,继承SingleValueholder类)。根据配置文件中的max、min计算出step值,据此在LinearDistribution类中调度execute()方法(通过反射机制调用SingleValueholder的setValue()方法)来设置此协议的初始值。

(4)  scheduleControls()

调度控制器。

作用:周期性调度执行Control类(通过execute()添加堆中)

该EDSimulator类中有两个成员:Control数组和Scheduler数组。获取Control类型的类实例,存储在Control数组中,相应也分配Scheduler类实例分配在Scheduler数组中。此配置文件中为:SingleValueObserver对象。最后将每一个对应的Control实例和Scheduler实例存放在ControlEvent对象(在peersim.edsim包中,为包访问权限,该对象有Control,Scheduler类型的成员和order,并且其构造数将其本身加入堆中)。Control时间的控制由step参数设定,该step参数最终将作为Scheduler调度器的step,用来控制下一次调度的时间。

(5)executeNext()

此函数首先取出小堆中的存储的时间最小的事件,将其保存PriorityQ.Event类型的变量ev中,根据此ev我们设置CommonState静态单例类。我们注意到在堆中存储的事件主要有:

(a)       ControlEvent对象

此消息主要保存Control,Scheduler和order,主要用来周期性的调度该control的执行,调度时机有Scheduler控制。适用于周期性的动作,如周期性失效检测等。

首先执行此对象的Control类型的成员,在此配置文件下该对象是SingleValueObserver类型,其使用IncrementStates来统计网络中节点信息并输出。然后在重新设置order,其值为next+=step。并再次将此ControlEvent对象(修正order)存入堆中。

其实,个人认为可以将事件机制理解为循环机制的一种改进版。把一个step可以当做一个周期,首先执行的就是ControlEvent事件,执行完了再将它加入到下一周期的开始时。而节点产生的事件,其时间的产生本质而言就是在当前周期内时间的随机数(可理解为next+Random.next(step))。那么,在一个周期内所做的就是:首先执行ControlEvent事件,然后再执行所有节点上的NextCycleEvent事件,此执行顺序本质上是随机的。

(b)       NextCycleEvent对象

此消息主要用来执行节点上实现了CDProtocol接口的协议,执行完毕再次加入堆中下次执行。因而其可以用来将循环机制转化到事件机制之中,其本质上也是周期性的执行。CDProtocol接口要求实现nextCycle()方法。

执行该对象的execute()方法,将根据CommonState类找到所要作用的协议、节点,然后调用该节点上的协议(这里是AvergeED协议)的nextCycle()方法。

该方法将利用UnreliableTransport传输层发送消息,其将根据配置文件中丢包情况调用UniformRandomTransport传输层的send()函数。发送消息本质上产生Avergemessage对象,并将之加入堆中,其时间的设置为CommonSatate.getTime()+delay(配置文件中配置)

发送完消息之后,再将此NextCycleEvent消息加入堆中,以便下一个周期中执行此消息,其中修改了其执行时间为CommonSatate.getTime()+step。

(c)      AvergeMessage对象(为peersim.edaggregation包中类,包访问权限)

通过实现EDProtocol接口的协议(即执行processEvent())进行处理;

当节点收到此消息后,就会调用AvergeED协议的processEvent()方法。对于接受此消息的节点,它将做两件书:更新自身节点的值,即两节点值和的一半;同时发送一个应答消息给发送节点,此时应答消息发送节点成员设置为空。

然后,原始发送节点收到应答消息后,简单将自身节点值进行更新即可。

 

附在PeerSim中事件驱动流程简图:


原创粉丝点击