【问题标题】:Continue execution after a particular condition is satisfied in Simpy在 Simpy 中满足特定条件后继续执行
【发布时间】:2021-02-26 06:24:10
【问题描述】:

我是 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)

上面的例子在car进程中的while条件下不断等待。 这是正确的做法吗?如果不是,如何处理? 提前致谢!

编辑和扩展(因为我无法评论这个大数据) 来自@Michael 的回答。

只是想澄清一下: 一旦满足条件(rand_num > 8),就会触发事件condition_flag 并设置为succeed()。这反过来又使暂停的car 进程恢复。之后,我们将重置事件condition_flag 以检测另一个触发器&succeed()。我的理解正确吗?

另外,由于我想模拟更多的汽车,所以对代码稍作修改:

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

我做错了什么吗?为什么进程不能对属于事件列表成员的事件进行让步?

【问题讨论】:

    标签: python simulation simpy


    【解决方案1】:

    当您屈服于某个事件时,您的进程会等待该事件触发。您可以通过调用该事件的成功或失败方法在该事件触发时触发。

    我更新了您的代码以使用事件而不是标志,见下文

    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')
    

    【讨论】:

    • 另请注意,多个进程可以在同一事件上产生。
    • 嗨@Michael,请参阅上面的编辑。我无法扩展它并等待事件列表。
    • 我想如果你只是在我的代码中添加更多的汽车,它会工作得很好。所有汽车都将在同一事件中让出并恢复。在以下行查看您的代码: condition_flag = [None] * num_of_cars 您在 if name == 'main' 行中创建 None 列表: condition_flag = simpy.Event(如果您将该行更改为:condition_flag = [] 并在创建汽车的循环内添加:condition_flag.append(simpy.Event(env)) 这将使您进入下一个错误,则 env) 仅用一个事件覆盖该列表
    猜你喜欢
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2013-09-09
    • 1970-01-01
    • 2017-02-03
    相关资源
    最近更新 更多