概述
前面写的异步编程的几篇文章:
- 异步编程 101: 是什么、小试Python asyncio
- 异步编程 101:Python async await发展简史
- 异步编程 101:写一个事件循环
废话不多说,上代码:
这个代码只适用于Python3.7,因为
asyncio.run()
在 Python3.7才提出
import asyncio
async def heavy_task():
await asyncio.sleep(2)
async def main():
for _ in range(100):
await heavy_task()
if __name__ == '__main__':
asyncio.run(main())
请问上面这个代码需要多久完成?答案是20秒,而不是我们期望的那样在2秒内完成。
理解原因需要先搞明白 await
到底干了什么:事件循环执行到 await
的时候,会把当前的协程挂起(暂停),然后看看当前的事件循环池里面有哪些其他可以执行的协程,接着继续执行其他的协程。
main()
中的 for 循环是一个整体, awaitheavy_task()
会把整个 main()
挂起,等到await的 heavy_task()
执行完了(也就是两秒后),接着再返回 main()
,从上次落下的地方继续。而上次落下的地方,还是在这个 for 循环里面的。
所以,这个程序是异步的吗?可以肯定的说是的,针对整个程序是异步的。但是对于 main()
,它的 for
循环还是阻塞的。
上述问题的根源在于:我们没能及时往事件循环里面添加协程。 for
循环要等到 heavy_task()
结束了再创建下一个协程。要解决这个可以用 asyncio.gather()
:
前面一篇文章里面我们的那个代码:先把所有的协程事先创建好,然后一次性交给 asyncio.gather()
。
import time
import asyncio
import aiohttp
async def fetch_async(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
status_code = resp.status
print(status_code)
async def visit_async():
start = time.time()
tasks = []
for _ in range(100):
tasks.append(fetch_async(URL))
await asyncio.gather(*tasks)
end = time.time()
print("visit_async tasks %.2f seconds" % (end - start))
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(visit_async())
如果你像我一样真正热爱计算机科学,喜欢研究底层逻辑,欢迎关注我的微信公众号:
最后
以上就是精明热狗为你收集整理的matlab中for循环的用法_异步编程 101:asyncio中的 for 循环的全部内容,希望文章能够帮你解决matlab中for循环的用法_异步编程 101:asyncio中的 for 循环所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复