在仿真过程中,事件类核心函数为进程模型提供有关事件的信息。这些事件由仿真核心管理,按照执行时间的顺序被存储在一个事件列表中。事件列表的队首事件为当前要执行的事件,而事件类核心函数使用事件句柄(Evhandle)来对事件进行操作。
OPNET 提供三个函数访问事件列表中的事件。
(1)op_ev_current()返回当前事件的句柄。
(2)以一个有效事件为参考点,进程可以通过调用op_ev_next()在事件列表中获得该事件的下一个事件。
(3)op_ev_seek_time()可以获得与输入的仿真时间最接近的那个事件的句柄。当一个进程接收某个事件,也就是说,该事件作用于本地进程模块自身,则该事件被看作时本地事件。因此op_ev_current()返回的肯定是本地事件,因为是这个事件唤醒本地进程的。而op_ev_next_local()返回下一个本地事件。事件类核心函数还支持管理并查找将来的事件。如果进程要遍历全部的事件,可以分为两步进行操作:
(1)调用op_ev_count()得到事件的个数,当然也可以采用op_ev_count_local()得到本地事件的个数。
(2)事件个数为循环语句的上限,对每个事件进行操作。
有时当事件到达时,进程模块却认为该事件已经过期无效,例如进程发送包是为了确保它将来没有成功发送时重新再发,于是进程调度一个将来5 分钟以后再次发送包的事件,但是2 分钟过后,收到一个确认表明刚才的包发送成功了,于是这个“将来5 分钟以后再次发送包的事件”就变得无效,这时可以调用op_ev_cancel()在收到“2 分钟过后的确认”后将这个无效的将来事件删除。而op_ev_pending()判断一个事件是否还在事件列表中等待调度。如果op_ev_cancel()试图删除一个在事件列表中不存在的事件,则会出错,因此一般op_ev_pending()配合op_ev_cancel()使用,确保能够正确删除事件。事件的两个常用属性分别是事件类型和调度时间。op_ev_type()可返回一个事件的类型,中断的类型在编程中用得较多,每种类型其实对应的是(1,2,3...)的整数索引号,OPNET常用的事件(也可称为中断,中断是事件起作用的结果)类型如如下表所示。
OPNET中断类型常数 | 描述 |
OPC_INTRPT_FAIL | 节点或链路失效中断 |
OPC_INTRPT_RECOVER | 节点或链路恢复中断 |
OPC_INTRPT_PROCEDURE | 程序调用中断 |
OPC_INTRPT_SELF | 自中断 |
OPC_INTRPT_STRM | 流中断 |
OPC_INTRPT_STAT | 状态中断 |
OPC_INTRPT_REMOTE | 来自外地进程的遥远中断 |
OPC_INTRPT_BEGSIM | 仿真开始中断 |
OPC_INTRPT_ENDSIM | 仿真结束中断 |
OPC_INTRPT_ACCESS | 进程模块用来获取包流队列中封包的中断 |
OPC_INTRPT_MCAST | 多播中断 |
OPC_INTRPT_PROCESS | 进程调用中断 |
自中断、遥远中断或多播中断有着它们各自的用途。自中断最常用,模拟进程的各种延时(将来某个时刻)的处理。由于进程可以调度多个同种类型的事件,因此光用事件类型来区分是不够的,OPNET 为每个事件分配一个事件号(不是自动分配的,是用户调度事件时手动分配的),op_ev_co
大多数事件源于某个模块,例如流中断源于发送包的模块,自中断、遥远中断和多播中断源于调度它们的进程模块。调用op_ev_src_id()获取产生这些事件的源模块ID号。但是有三种事件是没有源模块的,因为它们是仿真核心自动生成的,它们是:仿真开始事件bigsim,仿真结束事件endsim 和regular 事件。与op_ev_src_id()对应,事件的目的模块ID号可以通过op_ev_dst_id()获得。op_ev_equal()提供比较两个事件句柄的支持。如果是事件句柄相同,则认为它们是同一个事件,这在进程等待一个特定事件时很有用,具体来说,首先进程得到该特定事件的句柄,然后每接收一个事件将当前事件的句柄和这个特定事件句柄相比较,一直等到特定事件的到达,op_ev_count()得到事件的个数,op_ev_count_local()得到本地事件的个数。
事件可以调度(scheduled),也可以强制(forced)执行。如果事件按照事件列表中按照正常顺序执行,则称为调度。而强制执行的事件不用在事件列表中按照先进先出顺序排队,直接“插队”而立即执行。
事件生成的同时也可以要求绑定一些相关信息,以便给接收该事件的目的模块以相关信息的提示。OPNET 提供两种方法:
(1)采用op_ici_install()将界面控制信息(ICI)句柄与事件绑定,而op_ev_ici()获得该界面控制信息的句柄。
(2)使用状态信息(State information),它是比ICI 机制更快速的传递信息的方式。op_ev_state_install()将用户自定义的数据结构与事件相绑定,然后通过op_ev_state()返回该信息。另外有时可以通过op_ev_valid()来判断事件是否有效。它一般用在对一个事件的有效性感到怀疑的场合,如我们想知道一个事件是否仍然存在事件列表中,就可以调用op_ev_valid()先做判断再进行其他的事件操作。