Следующий код создает объект asyncio.Queue
и пытается заполнить и использовать эту очередь из двух разных сопрограмм, соответственно arrival()
и server()
.Очередь Python asyncio не обновляется
loop = asyncio.get_event_loop()
q = asyncio.Queue()
async def arrival(q):
print('ARRIVAL - Queue id:', id(q))
while True:
await asyncio.sleep(1)
item = random.choice(['item1', 'item2'..., 'item100'])
q.put(item)
print('ARRIVAL - added {}, qsize is now {}'.format(item, q.qsize()))
async def server(q):
print('SERVER - Queue id:', id(q))
while True:
item = await q.get()
print('SERVER - taking {}, qsize is now {}'.format(item, q.qsize()))
await asyncio.sleep(1.8)
print('SERVER - finished processing {}'.format(item))
tasks = [loop.create_task(arrival(q)), loop.create_task(server(q))]
loop.run_until_complete(asyncio.gather(*tasks))
Принцип заключается в следующем:
- Каждый 1 секунда, элемент добавляется к
q
- В любое время сервер свободен, он принимает следующий пункт в очереди или ждет его
- сервер занимает 1,8 секунды для обработки предмета
ожидаемый результат будет:
SERVER - Queue id: 12345678
ARRIVAL - Queue id: 12345678
ARRIVAL - added item1, qsize is now 1
SERVER - taking item1, qsize is now 0
ARRIVAL - added item2, qsize is now 1
SERVER - finished processing item1
SERVER - taking item2, qsize is now 0
ARRIVAL - added item3, qsize is now 1
ARRIVAL - added item4, qsize is now 2
SERVER - finished processing item2
SERVER - taking item3, qsize is now 1
ARRIVAL - added item5, qsize is now 2
ARRIVAL - added item6, qsize is now 3
SERVER - finished processing item3
SERVER - taking item4, qsize is now 2
Однако, когда я запускаю приведенный выше код, элементы в while True
петли в server()
никогда не выполняется, q.qsize()
всегда 0, а выход:
SERVER - Queue id: 12345678
ARRIVAL - Queue id: 12345678
ARRIVAL - added item1, qsize is now 0
ARRIVAL - added item2, qsize is now 0
ARRIVAL - added item3, qsize is now 0
ARRIVAL - added item4, qsize is now 0
ARRIVAL - added item5, qsize is now 0
...
кажется, что q
объекта никогда не обновляется на arrival()
(q.qsize()
всегда 0), и поэтому server()
никогда не знает о товарах, добавленных arrival()
.
Спасибо! Значимый бит вызывал 'await q.put (item)' вместо просто 'q.put (item)'. Имеет смысл, поскольку 'q.put' является сопрограммой, но почему-то я ее пропустил. – Jivan
@ Jivan да, хотел добавить, что это была одна из самых важных вещей, которые я изменил ... извините. & с новым годом! –
С другой стороны, замена 'asyncio.gather()' на 'asyncio.wait()', похоже, не имеет никакого эффекта, в этом случае, по крайней мере. Я должен исследовать разницу в документах. С новым годом! – Jivan