10.5.7.4 队列
asyncio.Queue为协程提供了一个先进先出的数据结构,这与线程的queue.Queue或进程的multiprocessing.Queue很类似。
import asyncio
async def consumer(n,q):
print('consumer {}:starting'.format(n))
while True:
print('consumer {}:waiting for item'.format(n))
item = await q.get()
print('consumer {}:has item {}'.format(n,item))
if item is None:
# None is the signal to stop.
q.task_done()
break
else:
await asyncio.sleep(0.01 * item)
q.task_done()
print('consumer {}:ending'.format(n))
async def producer(q,num_workers):
print('producer:starting')
# Add some numbers to the queue to simulate jobs.
for i in range(num_workers * 3):
await q.put(i)
print('producer:added task {} to the queue'.format(i))
# Add None entries in the queue
# to signal consumers to exit.
print('producer:adding stop signals to the queue')
for i in range(num_workers):
await q.put(None)
print('producer:waiting for queue to empty')
await q.join()
print('producer:ending')
async def main(loop,num_consumers):
# Create the queue with a fixed size so the producer
# will block until the consumers pull some items out.
q = asyncio.Queue(maxsize=num_consumers)
# Schedule the consumer tasks.
consumers = [
loop.create_task(consumer(i,q))
for i in range(num_consumers)
]
# Schedule the producer task.
prod = loop.create_task(producer(q,num_consumers))
# Wait for all of the coroutines to finish.
await asyncio.wait(consumers + [prod])
event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(event_loop,2))
finally:
event_loop.close()
用put()增加元素和用get()删除元素都是异步操作,因为队列大小可能是固定的(阻塞增加操作),或者队列可能为空(自身获取元素的调用)。
运行结果: