Я пытаюсь создать имитацию производителя/потребителя, когда потребитель обрабатывает партии партиями. Проблема заключается в том, что функция Store.get() удаляет элементы из магазина, как только он называется, но мне нужно ждать, пока я под названием выход:Simpy Store Batch Processing
import simpy
def producer(env, Q):
item = 0
while True:
yield Q.put(item)
print('Submit item:%d'%item)
item += 1
def consumer(env, Q):
while True:
yield env.timeout(20)
events = [Q.get() for i in range(4)]
items = yield env.all_of(events)
print([items for items in items.values()])
env = simpy.Environment()
maxQD = 2
Q = simpy.Store(env, capacity=maxQD)
env.process(producer(env, Q))
env.process(consumer(env, Q))
env.run(until=500)
Который производит следующий вывод:
Submit item:0
Submit item:1
Submit item:2
Submit item:3
Submit item:4
[0, 1, 2, 3]
Submit item:5
Submit item:6
Submit item:7
Submit item:8
[4, 5, 6, 7]
Submit item:9
Submit item:10
Submit item:11
Submit item:12
[8, 9, 10, 11]
...
с maxQD установлен в 2, я ожидал бы просто:
Submit item:0
Submit item:1
с блокировкой потребителя, пока она успешно не получает 4 пункта, и производитель не в состоянии добавить больше чем 2.
Вы можете сортировать исправить эту проблему, проверив LEN (Q.items):
import simpy
def producer(env, Q):
item = 0
while True:
yield Q.put(item)
print('Submit item:%d'%item)
item += 1
def consumer(env, Q):
while True:
yield env.timeout(20)
if len(Q.items) >= 4:
events = [Q.get() for i in range(4)]
items = yield env.all_of(events)
print([items for items in items.values()])
env = simpy.Environment()
maxQD = 4
Q = simpy.Store(env, capacity=maxQD)
env.process(producer(env, Q))
env.process(consumer(env, Q))
env.run(until=500)
Но вы все равно получите разочарование поведением, что прибудете() удаляет элементы перед выходом, что делает его похожим на 5 элементы были добавлены к Q (обратите внимание maxQD изменился до 4):
Submit item:0
Submit item:1
Submit item:2
Submit item:3
Submit item:4
[0, 1, 2, 3]
То, что вы наблюдаете, является предполагаемым поведением. env.all_of() не ждет, пока все события get * не смогут добиться успеха, но пока все не удастся. Каждое отдельное событие, которое вы передаете env.all_of(), является независимым и будет запущено как можно скорее. Таким образом, семантика этого примера не «дожидается, пока в магазине не будет 4 элемента», но «подождите, пока вы в конечном итоге не получите 4 элемента из магазина». –