学习 asyncio:异步运行一个有延迟的函数
Posted
技术标签:
【中文标题】学习 asyncio:异步运行一个有延迟的函数【英文标题】:Learning asyncio: Run a function with a delay asynchronously 【发布时间】:2020-11-02 22:42:47 【问题描述】:我已经尝试学习 asyncio 几天了,但我无法让这个示例函数工作。我想加快发出几百个 HTTP 请求的速度,但我想从简单开始。我希望能够指定我想要多少个请求。当我一直在调整一些东西时,我遇到了很多不同的错误,但我无法让它工作。
这是我的代码:
import asyncio
import time
async def say():
print("Started")
await time.sleep(3) #something that takes a long time like an http request
print("Finsihed")
loop = asyncio.get_event_loop()
asyncio.gather(say(),say(),say())
loop.run_forever()
我对此非常了解,我确信我在运行循环时做错了,但我不知道下一步该尝试什么。感谢您的帮助。
【问题讨论】:
您遇到了什么错误?您提供的第一步是对gather
的结果做一些事情,例如asyncio.run(asyncio.gather(...))
(那么您甚至不需要loop
)。
将await time.sleep(3)
更改为await asyncio.sleep(3)
,您应该会看到预期的输出。
你不能等待任意的事情。
只能等待可以等待的东西。这方面的例子是用async def
、任务和期货定义的东西。该页面上的示例都是这样。如果你想发出 HTTP 请求,你可以像那篇文章的作者那样使用 aiohttp。
@user4815162342 TIL。谢谢
【参考方案1】:
你的代码有几个问题:
您不能在 asyncio 代码中使用time.sleep()
,因为调用像 time.sleep()
这样的阻塞函数会阻塞整个事件循环。
你不能只调用asyncio.gather()
,你必须等待它。
您可能应该使用更新和更强大的asyncio.run()
API,而不是旧的loop.run_forever()
这是修复了这些问题的代码:
import asyncio
async def say():
print("Started")
await asyncio.sleep(3)
print("Finsihed")
async def main():
await asyncio.gather(say(), say(), say())
asyncio.run(main())
另请注意,您需要使用像 aiohttp 这样的异步感知库才能正确使用异步。
【讨论】:
非常感谢!我让它工作了。我最终使用 requests_async 但我认为相同的想法。我非常感谢您的彻底答复,但我还有一个问题。如果我想运行 say() x 次,如何创建一种添加 say() 来收集 x 次的方法?换句话说,我如何以编程方式定义我希望它运行多少次,然后将它多次添加到收集函数中,从而异步运行那么多次?以上是关于学习 asyncio:异步运行一个有延迟的函数的主要内容,如果未能解决你的问题,请参考以下文章
Python并发编程之学习异步IO框架:asyncio 中篇
Python学习---Python的异步---asyncio模块(no-http)