问题描述
我是 Simpy 的新手,我正在尝试实现一个简单的模拟,其中进程必须等到条件为 False 时,当条件变为 True 时,它必须继续执行其余的过程。 考虑简单的代码:
import simpy
import random
condition_flag = 0
def car(env):
while True:
global condition_flag
#wait for the condition to become true
while(condition_flag != 1):
pass
#reset condition flag
condition_flag = 0
print('Start parking at %d' % env.Now)
parking_duration = 5
yield env.timeout(parking_duration)
print('Start driving at %d' % env.Now)
trip_duration = 2
yield env.timeout(trip_duration)
def some_condition(env):
while True:
global condition_flag
rand_num = random.randrange(0,10)
if rand_num > 8:
condition_flag = 1
yield env.timeout(1)
env = simpy.Environment()
env.process(car(env))
env.process(some_condition(env))
env.run(until=15)
以上示例在 while
进程中的 car
条件下持续等待。
这是正确的做法吗?如果不是,如何处理?
提前致谢!
编辑和扩展(因为我无法评论这些大数据): 来自@Michael 的回答。
只是想澄清一下:
一旦满足条件(rand_num > 8
),就会触发事件condition_flag
并设置为success()。这反过来又使暂停的 car
进程恢复。之后,我们将重置事件 condition_flag
以检测另一个触发器 & success()。我的理解正确吗?
import simpy
import random
num_of_cars = 2
condition_flag = [None] * num_of_cars
def car(env,car_id):
while True:
global condition_flag
# wait for the condition to become true
print('wait for event')
yield condition_flag[car_id]
# reset condition flag
condition_flag[car_id] = simpy.Event(env)
print('event fired and reset')
print('Start parking at %d' % env.Now)
parking_duration = 5
yield env.timeout(parking_duration)
print('Start driving at %d' % env.Now)
trip_duration = 2
yield env.timeout(trip_duration)
def some_condition(env):
while True:
global condition_flag
rand_num = random.randrange(0,num_of_cars)
print(rand_num)
condition_flag[rand_num].succeed()
'''
if rand_num > 8:
print('condition meet ',env.Now)
# need to check if event has been reset
if condition_flag.triggered:
print('event has not been reset yet')
else:
condition_flag.succeed()
'''
yield env.timeout(1)
if __name__ == '__main__':
print('start')
env = simpy.Environment()
condition_flag = simpy.Event(env)
#env.process(car(env))
for i in range(num_of_cars):
env.process(car(env,I))
env.process(some_condition(env))
env.run(until=50)
print('stop')
以上代码运行后报错如下:
root@testuser-Vostro-3902:~/AtAI/Rack_Warehouse/LoRaSimulators/lorasim# python simple2.py
start
wait for event
wait for event
0
Traceback (most recent call last):
File "simple2.py",line 13,in car
yield condition_flag[car_id]
TypeError: 'Event' object does not support indexing
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "simple2.py",line 53,in <module>
env.run(until=50)
File "/usr/local/lib/python3.6/dist-packages/simpy/core.py",line 254,in run
self.step()
File "/usr/local/lib/python3.6/dist-packages/simpy/core.py",line 206,in step
raise exc
TypeError: 'Event' object does not support indexing
我做错了什么吗?为什么进程无法对属于事件列表成员的事件让步?
解决方法
当您屈服于某个事件时,您的进程会等待该事件触发。您可以通过调用该事件的成功或失败方法在该事件触发时触发。
我更新了您的代码以使用事件而不是标志,见下文
import simpy
import random
condition_flag = None
def car(env):
while True:
global condition_flag
# wait for the condition to become true
print('wait for event')
yield condition_flag
# reset condition flag
condition_flag = simpy.Event(env)
print('event fired and reset')
print('Start parking at %d' % env.now)
parking_duration = 5
yield env.timeout(parking_duration)
print('Start driving at %d' % env.now)
trip_duration = 2
yield env.timeout(trip_duration)
def some_condition(env):
while True:
global condition_flag
rand_num = random.randrange(0,10)
print(rand_num)
if rand_num > 8:
print('condition meet ',env.now)
# need to check if event has been reset
if condition_flag.triggered:
print('event has not been reset yet')
else:
condition_flag.succeed()
yield env.timeout(1)
if __name__ == '__main__':
print('start')
env = simpy.Environment()
condition_flag = simpy.Event(env)
env.process(car(env))
env.process(some_condition(env))
env.run(until=50)
print('stop')