Python asyncio wait_for同步

问题描述 投票:1回答:1

使用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将使其超时取决于协程所花费的时间,而不是基于协程内的各个异步调用。导致这种行为的幕后发生了什么,是否有办法修改行为以符合我的直觉?

python asynchronous python-asyncio sleep
1个回答
2
投票

导致此行为的幕后发生的事情

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

另一方面,asyncio.sleep会被仔细地编写,以便在您等待时立即暂停当前任务,并安排其在超时后恢复。这允许在协程程序睡眠时继续进行事件循环。它也允许通过以特殊方式“恢复”任务以使await引发异常,从而随时取消任务。

[通常,协程不等待任何东西,可以很好地表明它的书写方式不正确,并且仅是名称上的协程。等待是协程存在的原因,sleeper不包含。

有没有办法改变行为以符合我的直觉?

如果绝对必须从asyncio调用旧版阻止代码,请使用run_in_executor。您仍然必须在执行此操作时告诉asyncio,这意味着run_in_executor将如下所示:

sleeper

这将在单独的线程中执行睡眠(或任何其他阻塞调用)并暂停执行,直到完成为止,从而允许事件循环继续进行。请注意,“取消”这样的协程将仅放弃等待而不会真正取消睡眠,因为没有通用的机制可以这样做。

© www.soinside.com 2019 - 2024. All rights reserved.