Python 异之如何同时运行多个协程详解
作者:冷冻工厂 发布时间:2023-11-27 12:47:23
asyncio 的一个好处是我们可以同时运行许多协程。这些协同程序可以在一个组中创建并存储,然后同时一起执行。这可以使用 asyncio.gather() 函数来实现。
让我们仔细看看。
1. 什么是 Asyncio gather()
asyncio.gather() 模块函数允许调用者将多个可等待对象组合在一起。分组后,可等待对象可以并发执行、等待和取消。
它是一个有用的实用函数,可用于分组和执行多个协程或多个任务。
...
# run a collection of awaitables
results = await asyncio.gather(coro1(), asyncio.create_task(coro2()))
在我们可能预先创建许多任务或协程然后希望一次执行它们并等待它们全部完成后再继续的情况下,我们可以使用 asyncio.gather() 函数。
这是一种可能的情况,其中需要许多类似任务的结果,例如具有不同数据的相同任务或协程。
可等待对象可以并发执行,返回结果,并且主程序可以通过使用它所依赖的结果来恢复。
gather() 函数比简单地等待任务完成更强大。它允许将一组可等待对象视为单个可等待对象。
通过 await 表达式执行并等待组中的所有可等待对象完成。
从所有分组的等待对象中获取结果,稍后通过 result() 方法检索。
要通过 cancel() 方法取消的一组等待对象。
通过 done() 方法检查组中的所有可等待对象是否已完成。
仅当组中的所有任务完成时才执行回调函数。
2. 如何使用 Asyncio gather()
在本节中,我们将仔细研究如何使用 asyncio.gather() 函数。
asyncio.gather() 函数将一个或多个可等待对象作为参数。回想一下,可等待对象可能是协程、Future 或 Task。
因此,我们可以调用 gather() 函数:
多项任务
多个协程
任务和协程的混合
...
# execute multiple coroutines
asyncio.gather(coro1(), coro2())
如果 Task 对象被提供给 gather(),它们将已经在运行,因为 Tasks 被安排为创建的一部分。asyncio.gather() 函数将可等待对象作为位置参数。
我们不能创建可等待对象的列表或集合并将其提供给收集,因为这会导致错误。
...
# cannot provide a list of awaitables directly
asyncio.gather([coro1(), coro2()])
如果首先使用星号运算符 (*) 将其解压缩到单独的表达式中,则可以提供等待列表。
...
# gather with an unpacked list of awaitables
asyncio.gather(*[coro1(), coro2()])
如果协程提供给 gather(),它们会自动包装在 Task 对象中。gather() 函数不会阻塞。
相反,它返回一个代表可等待对象组的 asyncio.Future 对象。
...
# get a future that represents multiple awaitables
group = asyncio.gather(coro1(), coro2())
一旦创建了 Future 对象,它就会在事件循环中自动调度。awaitable 代表组,组中的所有 awaitable 都会尽快执行。这意味着如果调用者什么都不做,那么预定的可等待对象组将运行(假设调用者挂起)。
这也意味着您不必等待从 gather() 返回的 Future。
...
# get a future that represents multiple awaitables
group = asyncio.gather(coro1(), coro2())
# suspend and wait a while, the group may be executing..
await asyncio.sleep(10)
可以等待返回的 Future 对象,它将等待组中的所有可等待对象完成。
...
# run the group of awaitables
await group
等待从 gather() 返回的 Future 将返回可等待对象的返回值列表。
如果可等待对象没有返回值,则此列表将包含默认的“无”返回值。
...
# run the group of awaitables and get return values
results = await group
这通常在一行中执行。
...
# run tasks and get results on one line
results = await asyncio.gather(coro1(), coro2())
3. 列表中多个协程的 gather() 示例
预先创建多个协程然后再收集它们是很常见的。这允许程序准备要并发执行的任务,然后立即触发它们的并发执行并等待它们完成。
我们可以手动或使用列表理解将许多协程收集到一个列表中。
...
# create many coroutines
coros = [task_coro(i) for i in range(10)]
然后我们可以用列表中的所有协程调用 gather()。协程列表不能直接提供给 gather() 函数,因为这会导致错误。相反,gather() 函数要求将每个可等待对象作为单独的位置参数提供。
这可以通过将列表展开为单独的表达式并将它们传递给 gather() 函数来实现。星号运算符 (*) 将为我们执行此操作。
...
# run the tasks
await asyncio.gather(*coros)
将它们结合在一起,下面列出了使用 gather() 运行预先准备好的协程列表的完整示例。
# SuperFastPython.com
# example of gather for many coroutines in a list
import asyncio
# coroutine used for a task
async def task_coro(value):
# report a message
print(f'>task {value} executing')
# sleep for a moment
await asyncio.sleep(1)
# coroutine used for the entry point
async def main():
# report a message
print('main starting')
# create many coroutines
coros = [task_coro(i) for i in range(10)]
# run the tasks
await asyncio.gather(*coros)
# report a message
print('main done')
# start the asyncio program
asyncio.run(main())
运行该示例会执行 main() 协程作为程序的入口点。main() 协程然后使用列表理解创建一个包含 10 个协程对象的列表。然后将此列表提供给 gather() 函数,并使用星号运算符将其解压缩为 10 个单独的表达式。
然后 main() 协程等待从调用 gather() 返回的 Future 对象,暂停并等待所有调度的协程完成它们的执行。协程会尽快运行,报告它们独特的消息并在终止前休眠。
只有在组中的所有协程都完成后,main() 协程才会恢复并报告其最终消息。这突出了我们如何准备协程集合并将它们作为单独的表达式提供给 gather() 函数。
main starting
>task 0 executing
>task 1 executing
>task 2 executing
>task 3 executing
>task 4 executing
>task 5 executing
>task 6 executing
>task 7 executing
>task 8 executing
>task 9 executing
main done
来源:https://juejin.cn/post/7201838656894468155
猜你喜欢
- 下面给大家介绍下pandas读取CSV文件时查看修改各列的数据类型格式,具体内容如下所述:我们在调bug的时候会经常查看、修改pandas列
- 1 解决方案【方案一】载入模型结构放在全局,即tensorflow会话外层。'''载入模型结构:最关键的一步'
- 要在自己的网站上添加一个天气预报功能,是一个很普通的需求,实现起来也不是很难。今天来介绍几个简单的方法。使用第三方服务有这样的一种简单的方式
- 加密接口怎么测试?(1)写个函数或者方法,把要加密的参数使用这个函数过滤一遍,等于就是说把数据丢进去,加密了之后,再通过这个加密好的数据传输
- 概述全链接层 (Fully Connected Layer) 会把一个特质空间线性变换到另一个特质空间, 在整个网络中起到分类器的作用.ke
- 一、bs4解析import requestsfrom bs4 import BeautifulSoupimport datetimeif _
- 在ie7发布之前,Dean的addEvent/removeEvent可以称的上是完美了。IE7发布后,引入新的内存泄漏(这个我不是很确定,忘
- 本文讲述了python在Windows下安装setuptools(easy_install工具)的方法。分享给大家供大家参考,具体如下:【题
- 在python中,提到如何计算多维数组和矩阵,那一定会想到numpy。numpy定义了矩阵和数组,为它们提供了相关的运算。size中文解释为
- 百度AI接口的调用方法不必多介绍。官网地址人流量统计新建AipBodyAnalysisfrom aip import AipBodyAnal
- 本文实例讲述了Python中xml和json格式相互转换操作。分享给大家供大家参考,具体如下:Python中xml和json格式是可以互转的
- # encoding:utf-8import re # 使用正则 匹配想要的数据import requests # 使用requests得到
- 问题描述在某些问题背景下,需要确认是否多台终端在线,也就是会使用我们牛逼的ping这个命令,做一些的ping操作,如果需要确认的设备比较少,
- 为了更好的理解这些基本操作,下面会通过读取一个股票数据,来进行Pandas基本数据操作的语法介绍。# 读取文件(读取保存文件后面会专门进行讲
- 推荐阅读:go语言最新版激活教程可以点下这个链接查看。goland永久安装教程,点击此处查看。Go 这几年很火,小哈也蹭业余时间悄 * 学习一
- 随着网页制作热潮的兴起,Dreamweaver 4.0强大的功能深受众多网页制作者的喜爱。特别是Dreamweaver 4.0中有许多第三方
- 决策树原理:从数据集中找出决定性的特征对数据集进行迭代划分,直到某个分支下的数据都属于同一类型,或者已经遍历了所有划分数据集的特征,停止决策
- 一、设计说明设计这个自动化的目的是想要交替、重复地使用固定的几个分区(分区编号01~05)来保存数据,当最后一个分区就是快满的时候,我们会把
- 图片提取为了方便技术展示,我们选取素材为演员杨紫的一段演讲视频,用例仅为技术交流演示使用,不针对任何指定人。为达到我们AI换脸的目的,我们首
- random.randomrandom.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0random.