深入解析 Python 异步编程中的 `gather`、`as_completed` 和 `wait`

在现代 Python 开发中,异步编程已经成为了构建高性能、可扩展应用的关键技术之一。通过 asyncio 库,Python 提供了强大的异步功能,帮助开发者更好地管理并发任务,提升程序的效率和响应能力。asyncio 中的三个重要函数——gatheras_completedwait,是处理多个异步任务时非常有用的工具。

本文将深入介绍这三个函数,帮助你理解它们的工作原理、用法及适用场景,提升你在异步编程中的能力。

什么是异步编程?

异步编程是一种通过非阻塞方式处理并发任务的编程模型。在 Python 中,异步编程的核心是协程(coroutine)。协程允许你编写并发代码,但不需要像传统线程那样消耗额外的系统资源。asyncio 库是 Python 提供的官方库,用于处理异步编程,它使用事件循环(event loop)来调度和管理协程的执行。

在并发任务的处理中,如何有效地管理多个任务、等待任务的结果以及控制任务的执行顺序是非常重要的。asyncio 提供了多个工具来帮助开发者实现这一目标,其中 gatheras_completedwait 是最常用的三个函数。

1. asyncio.gather: 并行执行多个任务

什么是 gather

asyncio.gather 是一个非常强大的工具,它可以并行执行多个异步任务,并在所有任务完成后收集它们的结果。它接受多个协程任务作为参数,执行所有任务并等待它们完成。当所有任务都执行完毕后,gather 会返回一个包含所有任务结果的列表。

使用场景

  • 适用于并行执行多个任务,并在所有任务完成后收集结果。
  • 如果任务之间没有依赖关系,gather 是并行执行任务时的理想选择。

示例代码

import asyncioasync def task_1():await asyncio.sleep(1)return "Task 1 completed"async def task_2():await asyncio.sleep(2)return "Task 2 completed"async def task_3():await asyncio.sleep(3)return "Task 3 completed"async def main():# 并行执行多个任务results = await asyncio.gather(task_1(), task_2(), task_3())print(results)  # ['Task 1 completed', 'Task 2 completed', 'Task 3 completed']# 执行
asyncio.run(main())

输出结果:

['Task 1 completed', 'Task 2 completed', 'Task 3 completed']

在此示例中,asyncio.gather 并行执行了三个任务,并且最终返回了所有任务的执行结果。注意,gather 会等待所有任务完成才返回结果。

异常处理

如果某个任务在执行过程中抛出异常,gather 会立即抛出该异常。你可以通过 return_exceptions=True 参数使 gather 返回异常,而不是直接抛出。

async def task_with_error():raise ValueError("An error occurred!")async def main_with_error():try:await asyncio.gather(task_1(), task_with_error())except Exception as e:print(f"Caught an exception: {e}")# 执行
asyncio.run(main_with_error())

输出结果:

Caught an exception: An error occurred!

通过 return_exceptions=True,你可以捕获到异常并继续执行其他任务。

2. asyncio.as_completed: 按任务完成顺序获取结果

什么是 as_completed

asyncio.as_completed 是一个生成器函数,它允许你按任务完成的顺序获取任务的结果,而不是等待所有任务完成后才返回。这意味着它会在任务完成时逐个返回任务的结果。这个特性对于需要处理任务执行顺序的场景非常有用。

使用场景

  • 适用于需要按任务完成的顺序逐个处理任务结果的场景。
  • 当任务的执行时间不确定且任务间没有明确的顺序时,使用 as_completed 可以更有效地处理结果。

示例代码

import asyncioasync def task_1():await asyncio.sleep(2)return "Task 1 completed"async def task_2():await asyncio.sleep(1)return "Task 2 completed"async def main():tasks = [task_1(), task_2()]# 使用 as_completed 按任务完成顺序获取结果for result in asyncio.as_completed(tasks):print(await result)# 执行
asyncio.run(main())

输出结果:

Task 2 completed
Task 1 completed

在此示例中,虽然 task_1task_2 后开始执行,但是由于 task_2 执行时间更短,因此它首先完成,并且 as_completed 会首先返回它的结果。

异常处理

gather 类似,as_completed 也可以在任务抛出异常时捕获并抛出。你可以在使用 async for 循环时捕获异常。

async def task_with_error():await asyncio.sleep(1)raise ValueError("An error occurred!")async def main_with_error():tasks = [task_1(), task_with_error()]for result in asyncio.as_completed(tasks):try:print(await result)except Exception as e:print(f"Caught an exception: {e}")# 执行
asyncio.run(main_with_error())

输出结果:

Task 2 completed
Caught an exception: An error occurred!

3. asyncio.wait: 等待任务完成并进行批量处理

什么是 wait

asyncio.wait 是一个更灵活的函数,它允许你等待多个任务,并返回已完成的任务和未完成的任务。你可以通过设置 return_when 参数来控制何时返回结果。例如,设置为 asyncio.ALL_COMPLETED 表示等所有任务完成后返回,而 asyncio.FIRST_COMPLETED 则表示一旦有任务完成就返回。

使用场景

  • 适用于等待多个任务,并根据任务的完成情况进行批量处理的场景。
  • 你可以根据不同的条件(如任务完成或抛出异常)来灵活控制任务的执行。

示例代码

import asyncioasync def task_1():await asyncio.sleep(1)return "Task 1 completed"async def task_2():await asyncio.sleep(2)return "Task 2 completed"async def main():tasks = [task_1(), task_2()]done, pending = await asyncio.wait(tasks, return_when=asyncio.ALL_COMPLETED)for task in done:print(await task)# 执行
asyncio.run(main())

输出结果:

Task 1 completed
Task 2 completed

使用 return_when 参数

asyncio.wait 允许你根据不同的条件返回已完成的任务。例如,设置 return_when=asyncio.FIRST_COMPLETED 可以让你在第一个任务完成时返回结果。

async def main():tasks = [task_1(), task_2()]done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)for task in done:print(await task)# 执行
asyncio.run(main())

输出结果:

Task 1 completed

总结

  • asyncio.gather:适用于并行执行多个任务,等待所有任务完成并返回它们的结果。
  • asyncio.as_completed:适用于按任务完成顺序逐个处理任务的结果,尤其是在任务完成时间不确定的场景下。
  • asyncio.wait:适用于等待多个任务,并灵活地控制返回已完成的任务,支持不同的条件和超时处理。

通过合理选择这三个函数,你可以有效地管理和协调异步任务的执行,控制并发任务的数量,优化程序性能,并处理不同任务的执行顺序。这些工具对于构建高性能的异步应用是非常有帮助的。

希望本文能帮助你更好地理解和应用 asyncio 中的这三个重要函数。如果你有任何问题或想法,欢迎在评论区交流!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/483003.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能-卷积神经网络(学习向)

一.概述; 卷积神经网络(Convolutional Neural Network, CNN)是一种专门用于处理具有类似网格结构的数据(如图像)的深度学习模型。 主要用于处理机器视觉任务。 主要功能; 1.图像分类 2.目标检测 3.图像分割…

思维导图+实现一个登录窗口界面

QQ2024122-205851 import sys from PyQt6.QtGui import QIcon, QPixmap, QMovie from PyQt6.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QLabel, QVBoxLayout# 封装我的窗口类 class LoginWidget(QWidget):# 构造函数def __init__(self):# 初始化父类su…

使用 Pytorch 构建 Vanilla GAN

文章目录 一、说明二、什么是 GAN?三、使用 PyTorch 的简单 GAN(完整解释的代码示例)3.1 配置变量3.2 、PyTorch 加速3.3 构建生成器3.4 构建鉴别器 四、准备数据集五、初始化函数六、前向和后向传递七、执行训练步骤八、结果 一、说明 使用…

Windows常用DOS指令(附案例)

文章目录 1.dir 查看当前目录2.cd 进入指定目录3.md 创建指定目录4.cd> 创建指定文件5.rd 删除指定空目录6.del 删除指定文件7.copy 复制文件8.xcopy 批量复制9.ren 改名10.type 在命令行空窗口打开文件11.cls 清空DOS命令窗口12.chkdsk 检查磁盘使用情况13.time 显示和设置…

【Maven】Nexus私服

6. Maven的私服 6.1 什么是私服 Maven 私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的远程仓库(中央仓库、其他远程公共仓库)。一些无法从外部仓库下载到的构件,如项目组其他人员开发的…

【CSS】小球旋转loading加载动画

效果 css小球旋转loading动画 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document<…

Web day07 项目实战

目录 Restful风格&#xff1a; 代码结构&#xff1a; 1). Controller层 2). Service层 3). Mapper&#xff08;dao&#xff09;层 4).yml文件&#xff1a; 数据封装&#xff1a; 1). 手动结果映射 2). 起别名 3). 开启驼峰命名(推荐) 删除部门&#xff1a; 新增部门&a…

rest-assured multiPart上传中文名称文件,文件名乱码

rest-assured是一个基于java语言的REST API测试框架&#xff0c;在使用rest-assured的multipart 上传文件后&#xff0c;后端获取的文件名称乱码。截图如下&#xff1a; 原因是rest-assured multipart/form-data默认的编码格式是US-ASCII&#xff0c;需要设置为UTF-8。 Befo…

【Git操作】-- 将已存在的项目复制一份到另一个分组空间下

目录 1、需求描述 2、操作步骤 2.1 配置 2.2、git 上创建新项目 2.3 添加到旧的项目中 2.3、将新项目添加到待复制的项目上 3、Push an existing Git repository 4、浏览器打开新项目 nn_bigdata 5、其他&#xff1a;如果项目已经拉取到本地&#xff0c;那么可以使用以…

搭建环境-PHP简介及环境搭建教程

搭建环境-PHP简介及环境搭建教程 前言 在现代Web开发中,PHP是一种广泛使用的服务器端脚本语言,它以简洁、高效和跨平台的特性受到开发者的青睐。无论是小型网站还是大型企业应用,PHP都能提供强大的支持。本文将为您详细介绍PHP的基本概念、特点,以及如何搭建PHP开发环境。…

Python中通过点运算符来访问命名空间中参数args方法

Python中通过点运算符来访问命名空间中参数args方法 在Python中&#xff0c;在使用args进行参数传入时&#xff0c;通常是调用argparse模块的ArgumentParser来创建对象。这种设计虽然使得访问命令行参数更加方便&#xff0c;可以通过点运算符来访问命名空间中的参数。但是当封装…

Unity类银河战士恶魔城学习总结(P156 Audio Settings音频设置)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了音频的大小设置与保存加载 音频管理器 UI_VolumeSlider.cs 定义了 UI_VolumeSlider 类&#xff0c;用于处理与音频设置相关的…

基于单片机的WIFI、语音、储存、时钟、闹钟、定位系统

所有仿真详情导航&#xff1a; PROTEUS专栏说明-CSDN博客 目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DS1302时钟模块&#xff0c;通过LCD1602显示实时时间&#xff0c;也可以储存时间在AT2DC02中&#xff0c…

贪心算法专题(四)

目录 1. 单调递增的数字 1.1 算法原理 1.2 算法代码 2. 坏了的计算器 2.1 算法原理 2.2 算法代码 3. 合并区间 3.1 算法原理 3.2 算法代码 4. 无重叠区间 4.1 算法原理 4.2 算法代码 5. 用最少数量的箭引爆气球 5.1 算法原理 ​5.2 算法代码 1. 单调递增的数字…

Creating Server TCP listening socket *:6379: bind: No error

启动redis报错&#xff1a;Creating Server TCP listening socket *:6379: bind: No error 解决方案&#xff1a; 1、直接在命令行中输入 redis-cli.exe 2、输入shutdown&#xff0c;关闭 3、输exit&#xff0c;退出 4、重新输入 redis-server.exe redis.windows.conf&…

【HM-React】02. React基础-下

React表单控制 受控绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 function App(){const [value, setValue] useState()return (<input type"text" value{value} onChange{e > setValue(e.target.value)}/>) …

基于python的汽车数据爬取数据分析与可视化

一、研究背景 基于提供的代码片段和讨论&#xff0c;我们可以得出一个与网络抓取、数据处理和数据可视化相关的研究背景&#xff0c;该背景涉及到汽车行业。以下是研究背景的陈述&#xff1a; "在迅速发展的汽车行业中&#xff0c;准确和及时的数据对各方利益相关者至关…

BWO-CNN-BiGRU-Attention白鲸优化算法优化卷积神经网络结合双向门控循环单元时间序列预测,含优化前后对比

BWO-CNN-BiGRU-Attention白鲸优化算法优化卷积神经网络结合双向门控循环单元时间序列预测&#xff0c;含优化前后对比 目录 BWO-CNN-BiGRU-Attention白鲸优化算法优化卷积神经网络结合双向门控循环单元时间序列预测&#xff0c;含优化前后对比预测效果基本介绍模型描述程序设计…

使用 Monaco Editor 实现 ECharts 变量使用功能

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【深度学习】四大图像分类网络之AlexNet

AlexNet是由Alex Krizhevsky、Ilya Sutskever&#xff08;均为Hinton的学生&#xff09;和Geoffrey Hinton&#xff08;被誉为”人工智能教父“&#xff0c;首先将反向传播用于多层神经网络&#xff09;在2012年ImageNet图像分类竞赛中提出的一种经典的卷积神经网络。AlexNet在…