Simpy离散事件仿真(6)——专题指南(2)——Enviroments环境

1 环境

仿真环境(Enviroment)管理仿真时间、事件的调度和处理。它还提供了逐步完成或执行仿真的方法。

常规的仿真使用Enviroment。对于实时仿真,SimPy提供了RealtimeEnvironment (更多关于实时仿真的内容)。

 

2 仿真控制

SimPy在进行仿真时非常灵活。您可以运行仿真直到没有其他事件发生,或者直到达到某个仿真时间,或者直到触发某个事件。您还可以按照事件次序逐步进行仿真。此外,您可以任意组合以上方式进行仿真。

例如,您可以运行仿真直到发生有趣的事件。然后,您可以逐个事件地进行一段时间仿真;最后,直到不再有事件存在,并且您的进程都已终止,仿真结束。

这里最重要的方法是Environment.run():

(1)如果在没有任何参数(env.run())的情况下调用它,它将逐步完成仿真直到没有其他事件。

注意:如果您的进程永远运行(While True:yield env.timeout(1)),则此方法将永远不会终止(除非您通过按Ctrl-C键来终止脚本)。

(2)在大多数情况下,建议在达到某个仿真时间时停止仿真。因此,您可以通过until参数传递所需的时间,例如:env.run(until=10)

当内部时钟达到10时,仿真将停止,但不会处理为时间10安排的任何事件。这类似于时钟为0但(显然)尚未处理事件的新环境。

如果需要将仿真集成到图形用户界面中并绘制流程栏,则可以重复调用此函数并增加“until”值,并在每次调用后更新进度栏:

 

for i in range(100):
    env.run(until=i)
    progressbar.update(i)

 

(3)您也可以将任何事件传递给它,而不是将数字传递给run()。当事件被处理后,run()将返回。

假设当前时间为0,env.run(until=env.timeout(5))等同于env.run(until=5)。

您还可以传递其他类型的事件(请记住,进程也是一个事件):

import simpy

def my_proc(env):
    yield env.timeout(1)
    return 'Monty Python’s Flying Circus'

env = simpy.Environment()
proc = env.process(my_proc(env))
env.run(until=proc)
'Monty Python’s Flying Circus'

 

如果您需要逐个事件地执行仿真事件,环境提供peek()和step()。

peek()返回下一个计划事件的时间,如果没有计划的事件,则返回无穷大(float('inf'))。

step()处理下一个计划的事件。如果没有可用的事件,它将抛出EmptySchedule异常。

典型的用法如下:

until = 10
while env.peek() < until:
   env.step()

 

3 状态访问

环境允许您通过environment.now属性获取当前仿真时间。仿真时间是一个没有单位的数字,它通过超时事件增加。

默认情况下,时间从0开始,但在有其他需求时,您可以自定义初始时间传递给环境。

注意:尽管仿真时间在技术上是无单位的,但您可以假设它是以秒为单位的,并将其用作time.time()返回的时间戳来计算日期或星期几。

属性Environment.active_process相当于os.getpid(),它要么是None,要么是指向当前活动的进程。一个进程在执行其进程功能时处于活动状态。当它产生一个事件时,它变为不活动(或挂起)。

因此,从进程函数或进程函数调用的函数中访问此属性才有意义:

def subfunc(env):
    print(env.active_process)  # will print "p1"

def my_proc(env):
    while True:
        print(env.active_process)  # will print "p1"
        subfunc(env)
        yield env.timeout(1)

env = simpy.Environment()
p1 = env.process(my_proc(env))
env.active_process  # None
env.step()
<Process(my_proc) object at 0x7fcbe82aa3c8>
<Process(my_proc) object at 0x7fcbe82aa3c8>
env.active_process  # None

这方面的一个示例是资源系统:如果进程函数调用request()来请求资源,则资源通过env.active_process来确定请求进程。看看代码,看看我们是怎么做到的:-)。

 

4 创建事件

要创建事件,通常需要导入simpy.events,实例化事件类并将对环境的引用传递给它。为了减少键入的次数,环境提供了一些创建事件的快捷方式。例如,Environment.event()等同于simpy.events.event(env)。

其他快捷方式包括:

Environment.process()
Environment.timeout()
Environment.all_of()
Environment.any_of()

有关事件的更多详细信息,请参阅事件指南。

 

5 其他

自Python 3.3以来,生成器函数可以有一个返回值:

def my_proc(env):
    yield env.timeout(1)
    return 42

在SimPy中,这可用于为可由其他进程使用的进程提供返回值:
 

def other_proc(env):
    ret_val = yield env.process(my_proc(env))
    assert ret_val == 42

 

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值