asyncio.queue 奇怪的行为

asyncio.queue strange behaviour

此代码

import asyncio


@asyncio.coroutine
def foo(q):

    print("foo before", q.empty())
    q.put_nowait("yoba")
    print("foo after", q.empty())


@asyncio.coroutine
def bar(q):

    for _ in range(5):

        asyncio.async(foo(q))
        r = yield from q.get()
        print("bar received", r)


q = asyncio.Queue()
asyncio.get_event_loop().run_until_complete(bar(q))

生成此输出:

foo before True
foo after True
bar received yoba
foo before True
foo after True
bar received yoba
foo before True
foo after True
bar received yoba
foo before True
foo after True
bar received yoba
foo before True
foo after True
bar received yoba

为什么队列变空了,即使我没有yield from并且流量控制也没有return循环?我预计,在我将 return 流控制循环并决定 "pop" 数据之前,元素不会 "pop" 从队列中。

asyncio.Queue.put_nowait 的来源中:

if self._getters:
    assert not self._queue, (
        'queue non-empty, why are getters waiting?')

    getter = self._getters.popleft()
    self.__put_internal(item)

    # getter cannot be cancelled, we just removed done getters
    getter.set_result(self._get())

正如我们所见,如果至少有一个 get() 没有被满足,任何对 put_nowait() 的调用都会将一个项目放入队列,然后 立即将其弹出 ,队列没有机会处于非空状态。