在simpy中,进程(process)可以被看成是一个事件。当你执行yield的时候,这个事件就结束了,比如洗车仿真中,车要等待“洗”这个进程结束;机场仿真中,起飞要等待“登机”这个进程结束。
有一辆电动车,它在行驶后需要一段时间来充电,必须要充电完成后才可以继续行驶。
对于行驶过程,我们需要创建一个drive进程(process)。对于充电,我们要再创建一个charge进程。
每次车的停车的时候,都要执行充电(charge)程序,充电执行完后继续驾驶。
import simpy
class Car(object):
def __init__(self, env):
self.env = env
self.action = env.process(self.drive())
def drive(self):
while True:
print('开始停车并充电 %d' % self.env.now)
charge_duration = 5
yield self.env.process(self.charge(charge_duration))
print('开始驾驶 %d' % self.env.now)
trip_duration = 2
yield self.env.timeout(trip_duration)
# 这个charge的yield并不在循环中,所以执行完一个,process就会结束
def charge(self, duration):
yield self.env.timeout(duration)
env = simpy.Environment()
car = Car(env) # 将类实例化
env.run(until=15)
在工程上,我们往往将一个仿真流程封装为一个类,类中每个函数是一个进程(process)
开始停车并充电 0
开始驾驶 5
开始停车并充电 7
开始驾驶 12
开始停车并充电 14
有可能,我们不希望一直等待汽车充满电,我们会在它充电到一半的时候结束充电程序,然后开走。
每个进程都有一个interrupt方法。通过调用它,即可打断该process的等待。这个打断实际上是一个“错误信息”,所以使用try语句来处理该异常(否则程序会随着打断而结束)
import simpy
class Car(object):
def __init__(self, env):
self.env = env
self.action = env.process(self.drive)
@property
def drive(self):
while True:
print('开始停车并充电 %d' % self.env.now)
charge_duration = 5
try:
yield self.env.process(self.charge(charge_duration))
except simpy.Interrupt as err:
print("强行中断充电",err.args)
print('开始驾驶 %d' % self.env.now)
trip_duration = 2
yield self.env.timeout(trip_duration)
# 这个charge的yield并不在循环中,所以执行完一个,process就会结束
def charge(self, duration):
yield self.env.timeout(duration)
def driver(env, car):
yield env.timeout(3)
car.action.interrupt(123) # 这里的action是Car类构造函数中创建的process
env = simpy.Environment()
car = Car(env)
env.process(driver(env, car))
env.run(until=15)
在代码执行时,构造函数中的drive这个process和代码倒数第二行的driver两个process会被同时执行,并在第三秒时,由driver打断drive。
在处理异常时,可以使用err.args查看打断时所传入的参数。
开始停车并充电 0
强行中断充电 (123,)
开始驾驶 3
开始停车并充电 5
开始驾驶 10
开始停车并充电 12