Python asyncio队列未更新

时间:2016-12-31 14:13:53

标签: python queue python-asyncio

以下代码实例化asyncio.Queue对象,并尝试从两个不同的协程({1}}和arrival()填充和使用此队列。

server()

原则如下:

  • 每1秒钟,一个项目会添加到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.8秒

预期输出为:

q

但是,当我运行上面的代码时,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()始终为0,输出为:

q.qsize()

似乎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()始终为0),因此q.qsize()永远不会知道{{1}添加的项目}}

2 个答案:

答案 0 :(得分: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
...

答案 1 :(得分:1)

TL&DR :使用异步队列时,请确保同时等待put()和get()。

理性:在异步队列中的get()和put()函数中,它们都是协同例程,因此需要等待。

示例

await q.put(item)
await q.get(item)