当前位置:   article > 正文

asyncio.gather和asyncio.wait的区别_asyncio.gather 等待完成

asyncio.gather 等待完成

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))]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

但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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
>>>
Add 7 + 16
Add 8 + 17
Add 9 + 18
Add 1 + 10
Add 2 + 11
Add 3 + 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/102713
推荐阅读
相关标签
  

闽ICP备14008679号