Asyncio.gather vs Asyncio.wait


150

asyncio.gatherve asyncio.waitbenzer kullanımlar var gibi görünüyor: Ben yürütmek / beklemek istiyorum async bir sürü şey var (mutlaka bir sonraki başlamadan önce bitirmek için beklemek değil). Farklı bir sözdizimi kullanıyorlar ve bazı detaylarda farklılık gösteriyorlar, ancak işlevsellikte böylesine büyük bir örtüşmeye sahip 2 işleve sahip olmak benim için çok pitonik görünmüyor. Neyi kaçırıyorum?

Yanıtlar:


180

Genel durumlarda benzer olsa da ("birçok görev için çalıştır ve sonuçları al"), her işlevin diğer durumlar için belirli işlevleri vardır:

asyncio.gather()

Görevlerin üst düzeyde gruplandırılmasına izin veren bir Gelecek örneği döndürür:

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)

Bir gruptaki tüm görevler çağrılarak group2.cancel()veya hatta iptal edilebilir all_groups.cancel(). Ayrıca bakınız .gather(..., return_exceptions=True),

asyncio.wait()

İlk görev tamamlandıktan sonra veya belirli bir zaman aşımından sonra durdurulmayı bekleyen işlemleri destekler, daha düşük düzeyde işlem hassasiyeti sağlar:

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
"Tek yıldız işareti (* args),
anahtar sözcük içermeyen

42

asyncio.waitdaha düşük bir seviyedir asyncio.gather.

Adından da anlaşılacağı gibi, asyncio.gatheresas olarak sonuçların toplanmasına odaklanmaktadır. bir sürü geleceği bekler ve sonuçlarını belirli bir sıraya getirir.

asyncio.waitsadece gelecekleri bekler. sonuçları size doğrudan vermek yerine, tamamlanmış ve beklemedeki görevleri verir. değerleri kendiniz toplamanız gerekir.

Dahası, tüm vadeli işlemlerin bitmesini veya sadece ilkinin bitmesini beklemeyi belirtebilirsiniz wait.


Diyorsun ki it waits on a bunch of futures and return their results in a given order. 10000000000000 görevim varsa ve hepsi büyük veri döndürürse ne olur? tüm sonuç bellek patlaması yapacak?
Kingname

@Kingname ..wat
Matt Joiner

14

Ben de sadece listesini belirterek wait () bir grup coroutines sağlayabilir fark ettim:

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

Bu arada, gather () 'da gruplama sadece birden fazla koroutin belirtilerek yapılır:

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

20
Listeler aşağıdakilerle de kullanılabilir gather(), örn:asyncio.gather(*task_list)
tehfink

1
Jeneratörler de olabilir
Jab

Bu toplamayı komut dosyasının geri kalanını engellemeden nasıl kullanabilirsiniz?
thebeancounter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.