asyncio.gather和asyncio.wait的区别

asyncio.gather和asyncio.wait的区别

环境: python3.7.1

参考: https://stackoverflow.com/questions/42231161/asyncio-gather-vs-asyncio-wait

wait执行顺序是随机的,gather执行顺序是有序的

import asyncio
import time


async def add(x=1, y=2):
    print(f'Add {x} + {y}')
    await asyncio.sleep(2)
    return x+y


loop = asyncio.get_event_loop()
tasks = [add(x, y) for x, y in zip(range(1, 10), range(11, 20))]

wait执行的顺序每次都是不一样的

s = time.time()
loop.run_until_complete(asyncio.wait(tasks))
print(f'cost {time.time()-s}')
>>>
Add 4 + 14
Add 8 + 18
Add 5 + 15
Add 9 + 19
Add 7 + 17
Add 1 + 11
Add 2 + 12
Add 6 + 16
Add 3 + 13
cost 2.005099058151245

但gather执行但顺序是有序的

s = time.time()
loop.run_until_complete(asyncio.gather(*tasks))
print(f'cost {time.time()-s}')

loop.close()
>>>
Add 1 + 11
Add 2 + 12
Add 3 + 13
Add 4 + 14
Add 5 + 15
Add 6 + 16
Add 7 + 17
Add 8 + 18
Add 9 + 19
cost 2.0041399002075195

gather和wait都能添加一组future,但gather更支持任务分组,而wait支持更低级别的精细操作

  • gather可以对任务进行分组
import asyncio


async def add(x=1, y=2):
    print(f'Add {x} + {y}')
    await asyncio.sleep(2)
    return x+y

loop = asyncio.get_event_loop()

# gather的顺序是添加到gather时的顺序
group3 = asyncio.gather(*[add(x, y) for x, y in zip(range(7, 10), range(16, 19))])
group2 = asyncio.gather(*[add(x, y) for x, y in zip(range(4, 7), range(13, 16))])
group1 = asyncio.gather(*[add(x, y) for x, y in zip(range(1, 4), range(10, 13))])

# 可以单独取消一组任务
group2.cancel()

# 因为gather已经将future丢到loop中了,所以这里执行一次空future就把之前到future一起执行了
loop.run_until_complete(asyncio.gather())
>>>
Add 7 + 16
Add 8 + 17
Add 9 + 18
Add 1 + 10
Add 2 + 11
Add 3 + 12
  • wait则可以在第一个任务完成或指定时间后停止等待操作
async def add2(x=1, y=2):
    await asyncio.sleep(random.uniform(1, 5))
    return x+y
tasks = [add2(x, y) for x, y in zip(range(1, 10), range(11, 20))]
# wait可以在完成第一个任务完成或超时后等待停止
finished, unfinished = loop.run_until_complete(asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED))
print('get first result:')
for task in finished:
    print(task.result())

print(f'unfinished:{len(unfinished)}')

print('get more result in 2 seconds:')
finished2, unfinished2 = loop.run_until_complete(
    asyncio.wait(unfinished, timeout=2))
for task in finished2:
    print(task.result())
print(f"unfinished2:{len(unfinished2)}")

print("Get all other results:")
finished3, unfinished3 = loop.run_until_complete(asyncio.wait(unfinished2))
for task in finished3:
    print(task.result())
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值