展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Python并发编程:asyncio协程全面解析

Python并发编程:asyncio协程全面解析

asyncio和协程是Python中处理I/O密集型任务的高效并发方案,其核心在于通过事件循环实现单线程内的合作式多任务调度。1.协程由asyncdef定义,通过await暂停执行并释放控制权给事件循环;2.事件循环负责监控和调度就绪的协程,避免阻塞;3.使用asyncio.run()启动事件循环,并通过asyncio.gather()并发运行多个任务;4.相较于线程和进程,协程更轻量、无GIL限制,适合高并发I/O场景,而线程适用于需阻塞操作或传统GUI编程,进程则用于绕过GIL实现CPU密集型并行计算

本文目录

    asyncio和协程是Python中处理I/O密集型任务的高效并发方案,其核心在于通过事件循环实现单线程内的合作式多任务调度。1. 协程由async def定义,通过await暂停执行并释放控制权给事件循环;2. 事件循环负责监控和调度就绪的协程,避免阻塞;3. 使用asyncio.run()启动事件循环,并通过asyncio.gather()并发运行多个任务;4. 相较于线程和进程,协程更轻量、无GIL限制,适合高并发I/O场景,而线程适用于需阻塞操作或传统GUI编程,进程则用于绕过GIL实现CPU密集型并行计算。

    Python中如何实现并发编程?asyncio协程详解

    Python中实现并发编程,尤其是对于I/O密集型任务,asyncio和协程无疑是当前非常主流且高效的选择。它并非真正意义上的并行处理(即同时在多个CPU核心上运行),而是通过一种巧妙的“合作式多任务”机制,让程序在等待某个操作(比如网络请求、文件读写)完成时,能够切换到其他任务上,从而充分利用等待时间,显著提升程序的响应性和吞吐量。简单来说,它让你的单线程程序看起来像是在同时处理很多事情。

    Python中如何实现并发编程?asyncio协程详解

    解决方案

    要深入理解asyncio和协程,我们得从几个核心概念说起。asyncio是Python内置的异步I/O框架,而协程(coroutine)则是它实现并发的基础。

    首先,协程是一种特殊的函数,用async def关键字定义。它们不像普通函数那样一旦调用就必须执行到底,而是在遇到await关键字时,可以“暂停”自身的执行,将控制权交还给事件循环(Event Loop),让事件循环去调度其他准备就绪的协程。等到await的操作完成后,这个协程又可以从暂停的地方继续执行。这就像你在厨房烧水,水没开的时候你不会傻等,而是可以去切菜、洗碗,等到水开了再回来处理。

    Python中如何实现并发编程?asyncio协程详解

    事件循环则是asyncio的心脏。它负责监控所有注册的任务(也就是协程),当某个任务的等待条件满足时,就把它唤醒并调度执行。整个过程都在一个线程内完成,所以没有多线程的GIL(全局解释器锁)限制,这对于I/O密集型任务来说是个巨大的优势。

    使用asyncio的基本流程通常是这样的:

    Python中如何实现并发编程?asyncio协程详解
    1. 定义协程: 使用async def定义你的异步函数。
    2. 等待异步操作: 在协程内部,使用await关键字等待另一个协程、一个Future或一个Task的完成。例如,await asyncio.sleep(1)会暂停当前协程1秒,但不会阻塞整个事件循环。
    3. 运行事件循环: 通过asyncio.run()来启动事件循环并运行你的主协程。这是Python 3.7+推荐的入口点。

    举个简单的例子,感受一下:

    import asyncio
    import time
    
    async def task_a():
        print(f"Task A: 开始在 {time.strftime('%X')}")
        await asyncio.sleep(2) # 模拟I/O操作,等待2秒
        print(f"Task A: 结束在 {time.strftime('%X')}")
    
    async def task_b():
        print(f"Task B: 开始在 {time.strftime('%X')}")
        await asyncio.sleep(1) # 模拟I/O操作,等待1秒
        print(f"Task B: 结束在 {time.strftime('%X')}")
    
    async def main():
        print(f"主程序开始在 {time.strftime('%X')}")
        # 同时运行两个任务
        await asyncio.gather(task_a(), task_b())
        print(f"主程序结束在 {time.strftime('%X')}")
    
    if __name__ == "__main__":
        asyncio.run(main())

    运行这段代码,你会发现Task A和Task B的开始和结束时间是交错的,总耗时大约是2秒(最长那个任务的时间),而不是3秒。这就是协程的魅力。asyncio.gather()则是一个非常方便的工具,用于并发地运行多个协程并等待它们全部完成。

    Python并发编程中,协程与线程/进程有何不同?

    这大概是初学者最常问的问题之一了。说实话,它们都是实现并发的手段,但底层机制和适用场景差异巨大。

    首先是协程(Coroutines)。如前所述,它们是单线程内的“合作式多任务”。核心在于,协程在遇到await时会主动让出CPU,让其他协程有机会运行。这种切换是由程序自身控制的,非常轻量级,几乎没有上下文切换的开销。而且,因为它们运行在同一个线程里,所以不存在数据共享时的锁竞争问题(当然,如果你自己写出阻塞代码或者不当的共享,还是会出问题)。它们特别适合I/O密集型任务,比如网络请求、数据库查询、文件读写,这些任务大部分时间都在等待外部响应。Python的GIL对协程几乎没有影响,因为GIL只限制同一时刻只有一个线程执行Python字节码,而协程在一个线程内,只是在等待I/O时把控制权交给事件循环。

    接着是线程(Threads)。Python的threading模块提供了线程支持。线程是操作系统层面的概念,由操作系统调度,属于“抢占式多任务”。这意味着操作系统可以在任何时候中断一个线程,去运行另一个线程。线程之间的切换开销比协程大。最关键的是,Python有一个“全局解释器锁”(GIL)。GIL的存在是为了保护Python解释器的内部状态,确保同一时刻只有一个线程在执行Python字节码。这意味着,即使你有多个线程,对于CPU密集型任务,它们也无法真正并行地利用多核CPU。然而,对于I/O密集型任务,当一个线程在等待I/O时,GIL会被释放,允许其他线程运行,所以在某些I/O场景下,线程也能提供并发效果。

    最后是进程(Processes)。Python的multiprocessing模块允许你创建新的进程。进程是操作系统分配资源的最小单位,每个进程都有自己独立的内存空间,互不干扰。由于每个进程都有自己独立的Python解释器实例,所以它们完全绕过了GIL的限制,可以真正地并行利用多核CPU。但进程间的通信(IPC)相对复杂,而且创建和销毁进程的开销远大于线程和协程。它们是CPU密集型任务(比如大数据计算、图像处理)的首选。

    我个人觉得,如果你正在构建一个高性能的网络服务、爬虫或任何需要处理大量并发I/O的系统,asyncio往往是更优雅、更高效的选择。它让你的代码逻辑更清晰,避免了多线程带来的复杂锁机制和调试难题。但如果你的任务是计算密集型的,或者需要利用多核CPU,那么multiprocessing才是你的朋友。线程嘛,在一些需要与阻塞式C扩展交互或者传统GUI编程中,可能还有一席之地,但面对新的并发需求,其地位正在被协程和进程削弱。

    asyncio在实际项目中如何应用?常见陷阱与最佳实践

    asyncio在实际项目中应用非常广泛,尤其是在需要高并发、低延迟的场景。

    常见应用场景:

    • Web服务和API: FastAPI、aiohttp、Sanic等流行的异步Web框架都构建在asyncio之上,能轻松处理成千上万的并发请求。
    • 网络爬虫: 利用asyncio可以同时发起大量HTTP请求,大大提高爬取效率,而不会因为等待响应而阻塞。
    • 数据库交互: 很多数据库驱动(如asyncpg for PostgreSQL, aiomysql for MySQL)提供了异步接口,与asyncio配合能实现非阻塞的数据库操作。
    • 实时数据处理: 例如WebSocket服务器、消息队列消费者等,需要持续监听和处理事件的场景。
    • RPC服务: 构建高性能的远程过程调用服务。

    常见陷阱:

    1. 阻塞调用: 这是最常见的坑!在async def协程里不小心调用了同步的、会阻塞当前线程的函数(比如requests.get()、time.sleep()、同步的数据库操作),会直接阻塞整个事件循环,导致所有其他协程都停滞不前。asyncio的优势荡然无存。
    2. 忘记await: 你定义了一个async def函数,但调用它的时候忘了await。比如task_a()而不是await task_a()。这样task_a()仅仅创建了一个协程对象,但并没有把它调度到事件循环中去执行。你的任务根本不会跑起来。
    3. 异常处理不当: 在asyncio中,如果一个协程内部发生未捕获的异常,可能会导致整个事件循环停止,或者任务悄无声息地失败。特别是使用asyncio.gather()或asyncio.create_task()时,需要注意异常的传播和捕获。
    4. 死锁或活锁(虽然比多线程少见): 尽管协程是合作式的,但如果你在协程间设计了复杂的依赖和资源共享逻辑,仍然可能出现相互等待的“死锁”或一直重复尝试的“活锁”情况。

    最佳实践:

    • 拥抱异步库: 尽可能使用asyncio原生的或支持async/await语法的第三方库。例如,用aiohttp代替requests,用asyncpg代替psycopg2。
    • 隔离阻塞代码: 如果你真的需要调用一个阻塞的同步函数,不要直接在协程里调用。而是应该把它放到一个单独的线程池或进程池中执行,asyncio提供了loop.run_in_executor()方法来做这件事。这能确保主事件循环不会被阻塞。
    • 合理使用asyncio.create_task()和asyncio.gather(): 当你需要并发运行多个不相互依赖的协程时,使用asyncio.create_task()来创建任务并让它们在后台运行,然后你可以继续做其他事情。如果你需要等待所有任务完成并收集结果,asyncio.gather()是理想选择。
    • 细致的异常处理: 对可能抛出异常的await调用使用try...except块。对于asyncio.gather(),可以设置return_exceptions=True来捕获所有任务的异常,而不是让第一个异常就中断整个gather。
    • 设置超时: 对于网络请求等可能长时间无响应的操作,使用asyncio.wait_for()或asyncio.timeout()(Python 3.11+)设置超时,避免无限期等待。
    • 日志记录: 异步代码的调试可能比同步代码复杂,因为执行流程是交错的。详细的日志记录能帮助你追踪问题。

    除了asyncio,Python还有哪些并发方案?它们各自的适用场景是什么?

    当然,asyncio并非Python并发的唯一方案。Python标准库还提供了其他强大的工具,各自有其擅长的领域。

    首先是threading模块。这前面也提到了,它基于操作系统线程。虽然Python的GIL限制了它在CPU密集型任务上的并行能力,但对于I/O密集型任务,它仍然是一个可行的选项。比如,你可能有一个桌面应用,需要在一个线程里运行UI,同时在另一个线程里下载文件,这样UI就不会卡死。或者,当你使用的某些第三方库是同步阻塞的,并且没有提供异步接口时,用threading来运行这些阻塞操作,可能是最简单直接的办法。它比asyncio的学习曲线可能更平缓一些,因为模型更接近传统的同步编程。

    接着是multiprocessing模块。这是Python实现真正并行计算的利器。它通过创建独立的进程来绕过GIL,每个进程都有自己独立的内存空间和Python解释器。这意味着你可以充分利用多核CPU来执行CPU密集型任务,比如大规模数据分析、科学计算、图像视频处理等。但进程间通信(IPC)需要额外的机制(如队列、管道、共享内存),而且创建和管理进程的开销相对较大。如果你的任务主要是计算,并且可以分解成独立的子任务,那么multiprocessing是毋庸置疑的首选。

    最后,不得不提concurrent.futures模块。这个模块提供了一个高级接口,用于异步执行可调用对象。它内部封装了ThreadPoolExecutor(基于线程)和ProcessPoolExecutor(基于进程)。它的好处是提供了一个统一的API来管理线程池和进程池,让你无需直接操作底层的线程或进程对象。你只需要提交任务,然后等待结果。这对于那些不需要复杂异步I/O逻辑,只是想简单地并发执行一组函数的场景非常方便。例如,你可能有一堆文件需要处理,用ProcessPoolExecutor可以很容易地分发给多个CPU核心并行处理。或者你有一堆URL需要请求,但又不希望引入asyncio的复杂性,ThreadPoolExecutor也能派上用场。

    在我看来,选择哪种并发方案,真的要看你的具体需求和任务特性。没有银弹。一个复杂的系统,甚至可能需要混合使用这些方案:比如用asyncio处理外部网络I/O,用multiprocessing来执行后台的CPU密集型数据处理,再用threading来封装一些老旧的、阻塞的第三方库调用。理解它们的优缺点和适用场景,比盲目追逐最新技术更为重要。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Postman macOS版
    Postman macOS版

    Postman是一套面向API全生命周期的开发与测试平台,可在Mac上发送和调试多种协议请求,管理集合、环境及认证信息,并完成脚本测试、模拟服务、监控、文档发布和团队协作。它适合开发、测试及运维人员使用,提供个人免费方案。

    Docker Desktop macOS版
    Docker Desktop macOS版

    Docker Desktop 是 Docker 官方为 Mac 提供的容器开发环境,集成 Docker Engine、命令行工具、Compose、Build、Kubernetes 与图形化管理界面。

    Android Studio macOS版
    Android Studio macOS版

    Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。

    Xcode macOS版
    Xcode macOS版

    Xcode 是苹果面向 Mac 提供的官方集成开发环境,将代码编辑、项目构建、SwiftUI 实时预览、设备模拟、自动化测试、断点调试、性能分析和应用分发整合在同一套工作流中,适合开发与维护 iPhone、iPad、Mac、Apple Wa

    JetBrains WebStorm macOS版
    JetBrains WebStorm macOS版

    JetBrains WebStorm 是面向 JavaScript、TypeScript 和现代 Web 技术的专业集成开发环境,可智能理解项目结构,提供代码补全、重构、错误检查、运行调试、测试及 Git 工具。

    PhpStorm macOS版
    PhpStorm macOS版

    PhpStorm 是 JetBrains 推出的专业 PHP 集成开发环境,可在 Mac 上完成代码编写、智能检查、重构、调试、测试和数据库管理。它支持主流 PHP 框架、Composer、Git、Docker 与远程解释器。

    JetBrains PyCharm macOS版
    JetBrains PyCharm macOS版

    JetBrains PyCharm 是面向 Python 开发者的集成开发环境,提供智能补全、代码检查、重构、调试、测试、版本控制及虚拟环境管理功能。Mac 版兼容 Intel 与 Apple 芯片,核心功能可免费使用。

    JetBrains IntelliJ IDEA macOS版
    JetBrains IntelliJ IDEA macOS版

    IntelliJ IDEA 是 JetBrains 推出的专业集成开发环境,重点服务于 Java、Kotlin 与 JVM 项目开发。软件集成代码补全、静态检查、重构、调试、测试、版本控制及构建工具,并可借助插件扩展语言和框架支持。

    Visual Studio Code macOS版
    Visual Studio Code macOS版

    Visual Studio Code 是微软提供的免费代码编辑器,支持 macOS,并为 Intel 与 Apple 芯片 Mac 提供适配版本。软件集代码编辑、调试、Git 源代码管理、集成终端和扩展市场于一体。

    REAPER macOS版
    REAPER macOS版

    REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

    Adobe Audition macOS版
    Adobe Audition macOS版

    Adobe Audition 是面向播客、影视后期、音乐制作及内容创作者的专业音频工作站,提供波形精修、多轨录制与混音、频谱编辑、降噪修复、响度匹配和效果处理工具,并可与 Adobe Premiere 协同完成视频声音制作。

    Pro Tools macOS版
    Pro Tools macOS版

    Pro Tools 是 Avid 推出的专业数字音频工作站,覆盖多轨录音、无损剪辑、MIDI 编曲、插件处理、自动化混音及声音与画面同步等工作。它拥有 Intro、Artist、Studio 和 Ultimate 等方案。

    WINDOWS 更多
    PixPix 网页版
    PixPix 网页版

    PixPix 是面向品牌、卖家和内容团队的在线 AI 图片视频创作平台,提供图视频 Agent、无限画布、图片生成、视频生成、自然语言编辑及商品套图、产品精修和带货视频等电商工具。

    Postman Windows版
    Postman Windows版

    Postman 是面向 API 全生命周期的开发与协作平台。Windows 桌面版可用于构建和发送 HTTP、GraphQL、gRPC、WebSocket、MQTT 等请求,并提供环境变量、集合、脚本测试、模拟服务、监控、文档及团队工作区等

    Docker Desktop Windows版
    Docker Desktop Windows版

    Docker Desktop 为 Windows 开发者提供集成式容器环境,内置 Docker Engine、命令行工具、Compose、Build 与 Kubernetes 等组件,可在本机完成镜像构建、容器运行、日志查看和资源管理。

    Android Studio Windows版
    Android Studio Windows版

    Android Studio 是 Google 面向 Android 应用开发提供的官方集成开发环境,以 IntelliJ IDEA 为基础,集成智能代码编辑、Gradle 构建、设备模拟、界面预览、调试测试及性能分析工具,

    JetBrains WebStorm Windows版
    JetBrains WebStorm Windows版

    WebStorm 是 JetBrains 面向 JavaScript、TypeScript 和现代 Web 技术打造的集成开发环境。它提供项目级代码分析、智能补全、安全重构、导航搜索,并集成调试、测试、终端、Git 与常用前端工具,

    JetBrains PhpStorm Windows版
    JetBrains PhpStorm Windows版

    PhpStorm 是 JetBrains 面向 PHP 与现代 Web 开发打造的专业集成开发环境,提供代码补全、静态检查、重构、调试、测试、数据库、版本控制及前端语言支持。Windows 用户可直接下载安装程序,

    JetBrains PyCharm Windows版
    JetBrains PyCharm Windows版

    PyCharm 是 JetBrains 推出的 Python 集成开发环境,提供智能代码补全、错误检查、重构、调试、测试、Git、终端及 Jupyter Notebook 支持。统一版安装后可体验 30 天 Pro 功能,

    JetBrains IntelliJ IDEA Windows版
    JetBrains IntelliJ IDEA Windows版

    JetBrains IntelliJ IDEA 是以 Java、Kotlin 和 JVM 项目为核心的专业集成开发环境,提供智能补全、代码检查、安全重构、调试、测试、版本控制及构建工具集成。统一发行版的核心功能可免费用于商业和非商业项目,

    Visual Studio Code Windows版
    Visual Studio Code Windows版

    Visual Studio Code 是微软推出的免费代码编辑器,Windows 版集成智能补全、代码导航、调试、终端和版本控制,并可通过扩展添加语言、格式化及远程开发能力。它启动较快、配置灵活,

    REAPER Windows版
    REAPER Windows版

    REAPER 是 Cockos 推出的数字音频工作站,适用于录音、MIDI 编曲、音频编辑、混音、母带制作及声音设计。软件安装包小巧,支持多轨录制、灵活路由、自动化、第三方插件和脚本扩展,并提供完整功能的 60 天免费评估期。

    Adobe Audition Windows版
    Adobe Audition Windows版

    Adobe Audition 是面向播客、影视后期、广播与音乐制作的专业音频工作站,提供波形编辑、多轨混音、频谱分析、录音、降噪修复和效果处理等功能。Windows 版通过 Adobe Creative Cloud 安装和管理,

    Pro Tools Windows版
    Pro Tools Windows版

    Pro Tools 是 Avid 推出的专业数字音频工作站,提供多轨录音、音频剪辑、MIDI编曲、插件处理、自动化混音及影视声音制作能力。它适合音乐人、录音师、制作人和音频后期团队使用,并提供免费入门版、订阅方案及永久授权选择。