具有同步设置的异步功能
Posted
技术标签:
【中文标题】具有同步设置的异步功能【英文标题】:Async function with sync setup 【发布时间】:2020-08-25 21:00:01 【问题描述】:我是异步编程的新手。
我的理解是,它对于并行运行但涉及大量等待的任务很有用。例如,下载 10 个 zip 压缩文件并解压缩它们可以并行完成,但由于“下载”部分只是等待 CPU 的时间,因此 asyncio 在这里是一个有用的概念。如果我错了,请纠正我。
我看到的所有教程都遵循与上述类似的示例问题,并通过创建一堆等待对象来解决它,然后将它们一起等待。 (例如gather
)
但是,启动这样的异步操作对我来说似乎是一个常见的要求,例如下载一个文件,继续并行做其他工作,直到真正需要该文件,然后再检索它。这基本上就是“未来”所代表的。
我不明白如何使用异步函数来实现这一点。如果我不“等待”对download_file
的调用,那么它甚至不会执行初始设置并且不会开始下载。如果我立即“等待”调用,它将等待整个下载完成,我将无法并行执行任何工作。
我想出的唯一解决方案是让download_file
返回一个可等待的未来。这真的是最好的方法吗?如果是这样,那么异步的意义何在?如果我们仍然必须像在引入“异步”关键字之前那样使用期货之类的对象?
【问题讨论】:
我认为多线程可能是您正在寻找的。span> 尝试使用 asyncio 进行测试并在任务/协程的 top 处打印一些独特的内容,例如“开始文件名”,然后打印一些类似“停止文件名”和 协程的底部,查看事件循环是否在等待完成时切换到不同的任务。类似于此问答中的玩具示例 - Asyncio execution flow issue。 【参考方案1】:解决方案(在 asyncio 中)是使用类似的东西:
download_task = asyncio.create_task(download_file(...))
... code continues executing ...
这会在“后台”中生成download_file()
(因为 asyncio 是单线程的,所以没有真正在后台运行的引号)。然后,您可以继续您的业务,通常做其他事情,最重要的是,等待其他事情,当您需要完成下载时,使用await download_task
获取结果。
我想出的唯一解决方案是让
download_file
返回一个可等待的未来。
asyncio.create_task()
有效地将任何协程 (async def) 转换为可等待的未来。
如果是这样,那么异步的意义何在?如果我们仍然必须像引入“异步”关键字之前那样使用期货之类的对象?
关键是你有协程:一个非常方便的工具来实现和组合这些未来。您可以像编写普通的顺序代码一样编写诸如downlooad_file
代码之类的函数,然后让它与一堆其他异步代码并行运行。
【讨论】:
以上是关于具有同步设置的异步功能的主要内容,如果未能解决你的问题,请参考以下文章
最近项目中遇到了一个场景,其实很常见,就是定时获取接口刷新数据。那么问题来了,假设我设置的定时时间为1s,而数据接口返回大于1s,应该用同步阻塞还是异步?