gpt4 book ai didi

Python asyncio wait_for 同步

转载 作者:行者123 更新时间:2023-12-05 01:36:34 24 4
gpt4 key购买 nike

使用 Python 3.6.8

async def sleeper():
time.sleep(2)

async def asyncio_sleeper():
await asyncio.sleep(2)

await asyncio.wait_for(sleeper(), 1)

await asyncio.wait_for(asyncio_sleeper(), 1)

使用 time.sleep 不会超时,asyncio.sleep 会超时。

我的直觉是,在协程上调用 wait_for 会根据协程花费的时间来确定其超时时间,而不是根据协程中的各个异步调用。导致这种行为的幕后发生了什么,是否有办法修改行为以符合我的直觉?

最佳答案

What is going on behind the scenes that results in this behavior

最简单的答案是,asyncio 基于合作 多任务处理,而time.sleep 不合作。 time.sleep(2) 阻塞线程两秒钟,事件循环和所有,对此任何人都无能为力。

另一方面,asyncio.sleep 很小心 written这样当您 await asyncio.sleep(2) 时,它会立即挂起当前任务并安排事件循环在 2 秒后恢复它。 Asyncio 的“休眠”是隐式的,它允许事件循环在协程挂起时继续执行其他任务。相同的暂停系统允许 wait_for 取消任务,事件循环通过在这样的等待中“恢复”它来完成任务,即暂停的 await 引发异常。

一般来说,一个不等待任何东西的协同程序很好地表明它的编写不正确,并且只是名义上的协同程序。等待是协程存在的原因,sleeper 不包含任何协程。

is there a way to modify behavior to match my intuition?

如果您必须从 asyncio 调用遗留阻塞代码,请使用 run_in_executor .当您这样做时,您必须告诉 asyncio 并允许它执行实际的阻塞调用,如下所示:

async def sleeper():
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, time.sleep, 2)

time.sleep(或其他阻塞函数)将被移交给一个单独的线程,sleeper 将被挂起,在 time 时恢复。 sleep 完成了。与 asyncio.sleep() 不同,阻塞的 time.sleep(2) 仍会被调用并阻塞其线程 2 秒,但这不会影响事件循环,它的工作方式与使用 await asyncio.sleep() 时的方式类似。

请注意,取消等待 run_in_executor 的协程只会取消等待阻塞 time.sleep(2) 在另一个线程中完成。阻塞调用将继续执行直到完成,这是意料之中的,因为没有中断它的通用机制。

关于Python asyncio wait_for 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61876399/

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