Asyncio.Gather vs asyncio.wait


150

asyncio.gatherasyncio.wait이와 유사한 용도를 갖고있는 것 같다 : 나는 (반드시 다음 일이 시작되기 전에 완료 한 대기하지 않음)에 대한 / 대기를 실행하려는 것을 내가 비동기 가지의 무리가 있습니다. 그것들은 다른 구문을 사용하고 세부 사항이 다르지만 기능적으로 큰 겹치는 두 가지 기능을 갖는 것은 비현실적입니다. 내가 무엇을 놓치고 있습니까?

답변:


178

일반적인 경우와 비슷하지만 ( "많은 작업에 대한 결과를 가져오고") 각 기능에는 다른 경우에 대한 특정 기능이 있습니다.

asyncio.gather()

높은 수준의 작업 그룹화를 허용하는 Future 인스턴스를 반환합니다.

import asyncio
from pprint import pprint

import random


async def coro(tag):
    print(">", tag)
    await asyncio.sleep(random.uniform(1, 3))
    print("<", tag)
    return tag


loop = asyncio.get_event_loop()

group1 = asyncio.gather(*[coro("group 1.{}".format(i)) for i in range(1, 6)])
group2 = asyncio.gather(*[coro("group 2.{}".format(i)) for i in range(1, 4)])
group3 = asyncio.gather(*[coro("group 3.{}".format(i)) for i in range(1, 10)])

all_groups = asyncio.gather(group1, group2, group3)

results = loop.run_until_complete(all_groups)

loop.close()

pprint(results)

group2.cancel()또는 을 호출하여 그룹의 모든 작업을 취소 할 수 있습니다 all_groups.cancel(). 참조 .gather(..., return_exceptions=True),

asyncio.wait()

첫 번째 작업이 완료된 후 또는 지정된 시간 초과 후 중지 대기를 지원하여 작업의 정밀도를 낮 춥니 다.

import asyncio
import random


async def coro(tag):
    print(">", tag)
    await asyncio.sleep(random.uniform(0.5, 5))
    print("<", tag)
    return tag


loop = asyncio.get_event_loop()

tasks = [coro(i) for i in range(1, 11)]

print("Get first result:")
finished, unfinished = loop.run_until_complete(
    asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED))

for task in finished:
    print(task.result())
print("unfinished:", len(unfinished))

print("Get more results in 2 seconds:")
finished2, unfinished2 = loop.run_until_complete(
    asyncio.wait(unfinished, timeout=2))

for task in finished2:
    print(task.result())
print("unfinished2:", len(unfinished2))

print("Get all other results:")
finished3, unfinished3 = loop.run_until_complete(asyncio.wait(unfinished2))

for task in finished3:
    print(task.result())

loop.close()

5
"단일 별표 양식 (* args)은 키워드가 아닌 가변 길이 인수 목록을 전달하는 데 사용되고 이중 별표 양식은
키워드가있는

41

asyncio.wait보다 낮은 수준 asyncio.gather입니다.

이름에서 알 수 있듯이 asyncio.gather주로 결과 수집에 중점을 둡니다. 그것은 많은 선물을 기다리고 주어진 순서대로 결과를 반환합니다.

asyncio.wait단지 선물을 기다립니다. 결과를 직접 제공하는 대신 완료 및 보류중인 작업을 제공합니다. 수동으로 값을 수집해야합니다.

또한 모든 미래가 끝날 때까지 기다리거나 첫 번째로 끝나는 것을 지정할 수 wait있습니다.


당신은 말합니다 : it waits on a bunch of futures and return their results in a given order. 10000000000000 개의 작업이 있고 모두 큰 데이터를 반환하면 어떻게됩니까? 모든 결과는 메모리 붐을 만들 것인가?
Kingname

@Kingname ..wat
매트 소목 장이

14

또한 단순히 목록을 지정하여 wait ()에서 코 루틴 그룹을 제공 할 수 있음을 알았습니다.

result=loop.run_until_complete(asyncio.wait([
        say('first hello', 2),
        say('second hello', 1),
        say('third hello', 4)
    ]))

gather ()의 그룹화는 여러 코 루틴을 지정하여 수행됩니다.

result=loop.run_until_complete(asyncio.gather(
        say('first hello', 2),
        say('second hello', 1),
        say('third hello', 4)
    ))

20
gather()예를 들어 다음 과 함께 목록을 사용할 수도 있습니다 .asyncio.gather(*task_list)
tehfink

1
따라서 발전기도 가능
Jab

스크립트의 나머지 부분을 차단하지 않고이 수집을 어떻게 사용할 수 있습니까?
thebeancounter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.