SimPy is a process-based discrete-event simulation framework based on standard Python.
1. 概念理解
simpy 中的几个重点概念
- environment -环境,相当于一个计时器
- Process -对象,比如一个car 一个driver 都是process
- Event - 事件,仿真触发事件
- Resource- 资源,
2. SimPy in 10 Minutes
2.0 Installation
2.1 Basic Concepts
通过一个车辆停车和行驶的例子,
理解yield, env.now, env.timeout, env.poricess, env.run
的意义。
import simpy
def car(env):# 此处,car 就是一个process
while True:
print('Start parking at %d' % env.now) #env.now 当前仿真环境的时间
parking_duration = 5
yield env.timeout(parking_duration) # env.timeout(time)结束这个事件的时间
print('Start driving at %d' % env.now)
trip_duration = 2
yield env.timeout(trip_duration)
if __name__ == '__main__':
env = simpy.Environment()# 创建一个simpy 环境
env.process(car(env))# 开始car 这个进程
env.run(until=15)# 仿真的结束时间
#输出结果
Start parking at 0
Start driving at 5
Start parking at 7
Start driving at 12
Start parking at 14
Process finished with exit code 0
2.2 Process Interaction
process 之间可以相互影响
The
Process
instance that is returned byEnvironment.process()
can be utilized for process interactions. The two most common examples for this are to wait for another process to finish and to interrupt another process while it is waiting for an event.
wait
interrupt
import simpy
class Car(object):
def __init__(self, env):
self.env = env
self.action = env.process(self.run()) # 这里已经触发了 run 这个event
def run(self):
while True:
print(f"start parking and charging at {self.env.now}")
charge_duration = 5
try:# 未被打断执行的process:charge
yield self.env.process(self.charge(charge_duration))
except simpy.Interrupt:# 被打断后执行的动作
print(f"was interrupted. hope the cattery is full enough...")
print(f"start driving at {self.env.now}")
trip_duration = 2
yield self.env.timeout(trip_duration)
def charge(self, duration):
yield self.env.timeout(duration)
def driver(env, car):
yield env.timeout(3)
car.action.interrupt()# 这里打断了一个process
if __name__ == '__main__':
env = simpy.Environment()
car = Car(env)
env.process(driver(env, car)) # driver 这个process内含一个 interrupt
env.run(until=15)
# 运行结果
start parking and charging at 0
was interrupted. hope the cattery is full enough...
start driving at 3
start parking and charging at 5
start driving at 10
start parking and charging at 12
Process finished with exit code 0
2.3 Shared Resources
有三种resources
,下面简单介绍Resource
。
SimPy offers three types of
resources
that help you modeling problems, where multiple processes want to use a resource of limited capacity (e.g., cars at a fuel station with a limited number of fuel pumps) or classical producer-consumer problems.
In this section, we’ll briefly introduce SimPy’sResource
class.
resource 可以用 request()
方法,等到资源可用时 process 开始。
The resource’s
request()
method generates an event that lets you wait until the resource becomes available again. If you are resumed, you “own” the resource until you release it.
用 with
方法可以自动释放资源。
If you use the resource with the
with
statement as shown above, the resource is automatically being released.
If you callrequest()
withoutwith
, you are responsible to callrelease()
once you are done using the resource.
import simpy
def car(env,name,bcs,driving_time,charge_duration):
yield env.timeout(driving_time)
print(f"{name} arriving at {env.now}")
with bcs.request() as req:# 用 with 可以自动释放资源
yield req
print(f"{name} starting to charge at {env.now}")
yield env.timeout(charge_duration)
print(f"{name} leaving the bcs at {env.now}")
if __name__ == '__main__':
env = simpy.Environment()
bcs=simpy.Resource(env,capacity=2) # 创建资源,其容量为2
for i in range(4):
env.process(car(env,f"car {i}",bcs,i*2,5))
env.run()
2.4 How to Proceed
看官方文档和例子。