asyncio gather函数的用法

asyncio.gather(tasks1, task2, ...)的作用:

  • 并发执行多个协程 - 将多个协程封装, 这些协程会并发执行, 相当于同时异步启动多个任务.
  • 等待多个协程完成 - 会等待所有的协程执行结束后才返回结果, 从而避免需要手动等待每个协程完成.
  • 提取协程返回值 - 将各个协程的返回值合并到一个列表中返回, 便于获取执行结果。

举个例子:

import asyncio

async def func1():
    print('func1 started')
    await asyncio.sleep(2)
    return 'result of func1'

async def func2():
    print('func2 started')
    await asyncio.sleep(3)
    return 'result of func2'

async def main():
    res = await asyncio.gather(func1(), func2())
    print(res)

asyncio.run(main())
func1 started
func2 started
['result of func1', 'result of func2']

在这个例子里面, 我们定义的都是异步函数, 调用asynico.run来使整个程序run起来, 不然还需要我们手动的send(None)来执行代码, asyncio.run()内部会先创建一个事件循环,然后执行main()协程, 在这里使用了很多的await, 再次理解是 : await相当于递归进去, 让你先去执行这个await里面的东西, 等你执行完了再把值返回回来.

然后我们再理解下run在干什么, 他会一直run直到遇见StopIteration, 伪代码如下:

while True:
    try:
    	x = self.coro.send(None)
    except StopIteration as e:
        result = e.value
    else:
        func, arg = x
        func(arg)

而后面的着一个部分func(arg)正是完成最底层的那个任务的需求, 最底层可以使用一个awaitable的一个对象, 然后使用: await Awaitable((function, args)), 这个时候最底层函数释放执行权, 将执行权交给顶层函数, 顶层函数执行完了之后再send(None)下来, 继续完成后续的操作, 如果有返回值的话就返回值, 和递归很像, 但是递归强调的是分解任务, 而协程强调的是协作, 可以等, 并且让出执行权.

然后接着代码, 这里是res等于gather最终的返回值, 所以要先等到gather的运行结束, 然后gather调用两个func, 等到两个func都执行结束, 返回值交给res, 虽然一个需要 2 s 2s 2s一个需要 3 s 3s 3s但是gather会等到所有都结束了再传给res, 相当于省下了写join, 非常的方便

`asyncio.gather` 和 `asyncio.wait` 都是 Pythonasyncio 库中的两个用于并发执行多个异步任务的方法,但它们之间有显著的不同。 1. **asyncio.gather()**: - 这个函数用于一次性调度并等待多个协程(coroutines)的完成。它接受一组协程作为参数,返回一个 Future 对象,当所有协程都完成时,Future 将解析为包含每个协程结果的一个元组。如果任何一个协程抛出了异常,那么整个 `gather` 也会立即停止,返回的 Future 将包含第一个失败协程的错误信息。 - 示例: ```python import asyncio async def task1(): await asyncio.sleep(1) return "Task1 result" async def task2(): await asyncio.sleep(2) return "Task2 result" tasks = [task1(), task2()] results = await asyncio.gather(*tasks) print(results) # {"Task1 result", "Task2 result"} ``` 2. **asyncio.wait()**: - `wait` 函数则更底层,它接收一个可迭代的协程集合和一个超时时间。它会返回两个列表:一个是已完成的任务,另一个是还在运行或挂起的任务。这意味着你需要手动处理这些返回值,可能需要使用 `asyncio.all_tasks()` 或者 `asyncio.shield()` 来确保所有任务都被正确地收集和处理。 - 示例: ```python import asyncio async def task1(): await asyncio.sleep(1) return "Task1 result" async def task2(): await asyncio.sleep(2) return "Task2 result" tasks = [task1(), task2()] done, pending = await asyncio.wait(tasks) completed_results = [t.result() for t in done] print(completed_results) ``` 注意,如果你不提供超时时间,`wait` 只会在所有任务完成后才会结束。 总结来说,`asyncio.gather()` 是一个简洁的方式,适合于不需要太多控制流程、只需要等待所有任务完成的情况;而 `asyncio.wait()` 提供了更多的灵活性,但需要手动管理任务的状态。如果你不确定具体需求,`gather` 更加推荐,因为它更易于理解和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

d3ac

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值