简单聊一下 Python asyncio

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等

希望看什么,评论或者私信告诉我!

一、前言

最近看到很多关于 asyncio 的代码,所以本篇文章,我们需要详细聊一下 asyncio,不会有过多的关于 asyncio 本身函数使用的例子,重点关注是什么以及为什么,asyncio 函数相对较简单。

二、asyncio

2.1 asyncio 是什么?

  • 本质 :asyncio 是基于协程的,提供了一套编写单线程并发代码的框架。它使用 async 和 await 语法来定义和执行异步操作,从而避免了传统的回调方式,代码更加直观和易于维护。asyncio 往往是构建 IO 密集型和高层级 结构化 网络代码的最佳选择。

  • 三条原则:

    1. 异步性 :使用 async 定义异步函数,await 用于挂起阻塞操作,如 IO 请求。
    2. 事件循环 :asyncio 提供事件循环来管理和调度执行异步任务。
    3. 协程:异步函数在 Python 中被称为协程,它们是可等待对象,可以在事件循环中被挂起和恢复。

2.2 asyncio 解决了什么问题

  • 起源 :asyncio 是 Python 用于解决异步 IO 编程的标准库,它在 Python 3.4 版本中引入。它的出现是为了提供一种简单的方式来编写并发代码。在此之前,Python 通过多线程和多进程等方式实现并发,但这些方式在性能和易用性上存在限制。

  • 对比状态:

    • 出现之前 :Python 开发者需要依赖 threading 或 multiprocessing 模块来实现并发,这不仅编程模型复杂,而且在处理大量并发网络连接时效率低下。
    • 出现之后 :asyncio 提供了事件循环和协程的概念,使得开发者能够以更低的开销实现大规模 IO 密集型任务的并发。

    怎么理解?来看一下一个具体的案例:

    • 背景:假设有一个需要从多个网站上下载数据的任务。

    • 解决方案 :使用 asyncio 创建异步函数来发起网络请求,并且并发地等待所有请求完成,而不是顺序地一个接一个地请求,从而大大提高了效率。

    • 代码片断:

    python 复制代码
    import asyncio
    import aiohttp
    
    async def download_site(session, url):
        async with session.get(url) as response:
            print(f"Read {response.content_length} from {url}")
    
    async def download_all_sites(sites):
        async with aiohttp.ClientSession() as session:
            tasks = []
            for url in sites:
                task = asyncio.create_task(download_site(session, url))
                tasks.append(task)
            await asyncio.gather(*tasks)
    
    sites = ["https://example1.com", "https://example2.com"]
    asyncio.run(download_all_sites(sites))

    在这个例子中,我们定义了两个异步函数 download_site 和 download_all_sites。download_site 函数用于下载单个网站的内容,而 download_all_sites 函数则创建了一个 ClientSession 并发起多个异步请求,最后使用 asyncio.gather 并发等待所有的请求完成。通过这种方式,我们可以利用 asyncio 实现高效的并发 IO 操作。

    在 asyncio 出现之前,Python 开发者常用 threading 模块来实现并发。以下是一个使用 threading 模块下载多个网站内容的例子:

    python 复制代码
    import threading
    import requests
    from time import time
    
    def download_site(url):
        with requests.get(url) as response:
            print(f"Read {len(response.content)} from {url}")
    
    def download_all_sites(sites):
        threads = []
        for url in sites:
            thread = threading.Thread(target=download_site, args=(url,))
            thread.start()
            threads.append(thread)
        for thread in threads:
            thread.join()
    
    if __name__ == "__main__":
        sites = ["https://example1.com", "https://example2.com"] * 10
        start_time = time()
        download_all_sites(sites)
        duration = time() - start_time
        print(f"Downloaded {len(sites)} sites in {duration} seconds")

2.23 asyncio 例子

直观的感受一下:

python 复制代码
import asyncio
async def say_hello():
    print("Hello,")
    await asyncio.sleep(1)
    print("World!")
asyncio.run(say_hello())

其他方法的使用,我们就不过多的举例子了,具体可以参考官方文档,相对较简单!

三、总结

本文详细介绍了Python中的asyncio库,包括其本质、解决的问题以及提供的示例。asyncio是基于协程的框架,使用async和await语法来定义和执行异步操作,避免了传统的回调方式,适合构建IO密集型和高层级结构化网络代码。它解决了Python中多线程和多进程方式实现并发时的性能和易用性限制。最后,提供了一个简单的示例来展示asyncio的使用。

相关推荐
一条大祥脚5 分钟前
CuTe 与 CuTe DSL:从 C++ 模板元编程到 Python DSL 的 GPU 编程演进
开发语言·c++·python·cutlass·cute·cute dsl
早起CaiCai14 分钟前
【2023-01 OM】利用深度学习算法融合异质观测实现海洋场降尺度
人工智能·深度学习·算法
周杰伦的稻香21 分钟前
AI 助手 2.0:多轮对话、卡片化与文章页感知
人工智能
学长毕设28 分钟前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
Martina_032136 分钟前
AI生成3D场景从白模换成精模后镜头全偏了?用6步检查单位、枢轴与层级替换
图像处理·人工智能·3d·ai·自然语言处理·材质·1024程序员节
10年前端老司机40 分钟前
Milvus 8种检索能力实践
数据库·python·agent
梦里寻码1 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
狒狒AI1 小时前
手绘白板动画的生产线拆解:AI 出图、笔迹对齐、镜头渲染七道工序(附 21 个开源脚本)
人工智能·aigc
鶴哥只手遮天1 小时前
《Redis 8.10.3 深度剖析》系列 ·第 10 章 Hash 一:`listpack`、`hashtable` 与 `LISTPACK_EX`
redis·后端·开源
用户2763965765101 小时前
上手 GitHub 官方 Spec Kit:AI 编码别再裸奔,先写 spec 再出码,SDD规约开发
人工智能