gpt4 book ai didi

python - 为什么 asyncio 队列等待 get() 会阻塞?

转载 作者:行者123 更新时间:2023-12-02 14:05:16 37 4
gpt4 key购买 nike

为什么awaitqueue.get()会阻塞?

import asyncio

async def producer(queue, item):
await queue.put(item)

async def consumer(queue):
val = await queue.get()
print("val = %d" % val)

async def main():
queue = asyncio.Queue()
await consumer(queue)
await producer(queue, 1)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

如果我在consumer()之前调用生产者(),它工作得很好也就是说,下面的代码可以正常工作。

async def main():
queue = asyncio.Queue()
await producer(queue, 1)
await consumer(queue)

为什么不awaitqueue.get()将控制权交还给事件循环,以便生产者协程可以运行,该协程将填充队列,以便queue.get()可以返回。

最佳答案

您需要并行启动消费者和生产者,例如像这样定义main:

async def main():
queue = asyncio.Queue()
await asyncio.gather(consumer(queue), producer(queue, 1))

如果由于某种原因你无法使用gather,那么你可以这样做(相当于):

async def main():
queue = asyncio.Queue()
asyncio.create_task(consumer(queue))
asyncio.create_task(producer(queue, 1))
await asyncio.sleep(100) # what your program actually does

Why isn't await queue.get() yielding control back to the event loop so that the producer coroutine can run which will populate the queue so that queue.get() can return.

await queue.get() 正在将控制权交还给事件循环。但是await意味着等待,所以当你的main协程说await Consumer(queue)时,这意味着“恢复我”一旦consumer(queue)完成。”由于消费者(队列)本身正在等待某人生产某些东西,因此您会遇到典型的死锁情况。

反转顺序之所以有效,是因为您的生产者是一次性的,因此它会立即返回给调用者。如果您的生产者碰巧等待外部源(例如套接字),那么您也会遇到死锁。无论生产者消费者如何编写,并行启动它们都可以避免死锁。

关于python - 为什么 asyncio 队列等待 get() 会阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56377402/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com