Asyncio.gather बनाम asyncio.wait


150

asyncio.gatherऔर asyncio.waitलगता है कि इसी तरह के उपयोग होते हैं: मेरे पास एसिंक्स चीजों का एक गुच्छा है जिसे मैं निष्पादित करना चाहता हूं / इंतजार करना चाहता हूं (जरूरी नहीं कि अगले एक के शुरू होने से पहले खत्म होने की प्रतीक्षा कर रहा हो)। वे एक अलग वाक्यविन्यास का उपयोग करते हैं, और कुछ विवरणों में भिन्न होते हैं, लेकिन मुझे लगता है कि कार्यक्षमता में इतना बड़ा ओवरलैप होने के लिए मेरे पास 2 कार्य हैं। मैं क्या खो रहा हूँ?

जवाबों:


178

हालांकि सामान्य मामलों में समान ("कई कार्यों के लिए परिणाम प्राप्त करें"), प्रत्येक फ़ंक्शन में अन्य मामलों के लिए कुछ विशिष्ट कार्यक्षमता है:

asyncio.gather()

उच्च स्तर के कार्यों की अनुमति देते हुए, भविष्य का उदाहरण देता है:

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) का उपयोग एक गैर-कीवर्डेड, चर-लंबाई तर्क सूची को पास करने के लिए किया जाता है, और डबल तारांकन फॉर्म का उपयोग किसी कीवर्डेड, चर-लंबाई तर्क सूची को पास करने के लिए किया जाता है"
Laycat

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

मैंने यह भी देखा कि आप सूची में निर्दिष्ट करके प्रतीक्षा में () कॉरटाइन्स का एक समूह प्रदान कर सकते हैं:

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

जबकि एकत्रित () में समूहीकरण केवल कई कोरआउटों को निर्दिष्ट करके किया जाता है:

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)
तेहिंक

1
तो जनरेटर
Jab

बाकी स्क्रिप्ट को ब्लॉक किए बिना आप इस इकट्ठा का उपयोग कैसे कर सकते हैं?
thebeancounter
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.