2016-12-31 6 views
1

Следующий код создает объект 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().

ответ

2

я получил это работает так, как вы хотите, чтобы:

import asyncio 
import random 

random.seed(31415) # get reproducible runs 

ITEMS = ['item{}'.format(i) for i in range(100)] 

async def arrival(q): 
    queue_object_id = id(q) 
    print('ARRIVAL - Queue id:', queue_object_id) 
    while True: 
     await asyncio.sleep(1) 
     item = random.choice(ITEMS) 
     await q.put(item) 
     size = q.qsize() 
     print('ARRIVAL - added {}, qsize is now {}'.format(item, size)) 

async def server(q): 
    queue_object_id = id(q) 
    print('SERVER - Queue id:', queue_object_id) 

    while True: 
     item = await q.get() 
     size = q.qsize() 
     print('SERVER - taking {}, qsize is now {}'.format(item, size)) 
     await asyncio.sleep(1.8) 
     print('SERVER - finished processing {}'.format(item)) 

loop = asyncio.get_event_loop() 
q = asyncio.Queue() 
cors = asyncio.wait([arrival(q), server(q)]) 
loop.run_until_complete(cors) 

, к сожалению, я не отслеживать все изменения, я должен был сделать ... извините. но я уверен, что вы узнаете различия и почему они имеют значение.

это производит вывод:

SERVER - Queue id: 140540011741592 
ARRIVAL - Queue id: 140540011741592 
ARRIVAL - added item75, qsize is now 1 
SERVER - taking item75, qsize is now 0 
ARRIVAL - added item36, qsize is now 1 
SERVER - finished processing item75 
SERVER - taking item36, qsize is now 0 
ARRIVAL - added item57, qsize is now 1 
ARRIVAL - added item5, qsize is now 2 
SERVER - finished processing item36 
SERVER - taking item57, qsize is now 1 
ARRIVAL - added item69, qsize is now 2 
ARRIVAL - added item67, qsize is now 3 
SERVER - finished processing item57 
SERVER - taking item5, qsize is now 2 
ARRIVAL - added item53, qsize is now 3 
ARRIVAL - added item16, qsize is now 4 
SERVER - finished processing item5 
SERVER - taking item69, qsize is now 3 
ARRIVAL - added item91, qsize is now 4 
... 
+0

Спасибо! Значимый бит вызывал 'await q.put (item)' вместо просто 'q.put (item)'. Имеет смысл, поскольку 'q.put' является сопрограммой, но почему-то я ее пропустил. – Jivan

+1

@ Jivan да, хотел добавить, что это была одна из самых важных вещей, которые я изменил ... извините. & с новым годом! –

+0

С другой стороны, замена 'asyncio.gather()' на 'asyncio.wait()', похоже, не имеет никакого эффекта, в этом случае, по крайней мере. Я должен исследовать разницу в документах. С новым годом! – Jivan

Смежные вопросы