पायथन में समवर्ती प्रोग्रामिंग की शक्ति को अनलॉक करें। उच्च-प्रदर्शन, स्केलेबल एप्लिकेशन बनाने के लिए Asyncio कार्यों को बनाना, प्रबंधित करना और रद्द करना सीखें।
पायथन Asyncio में महारत हासिल करना: कार्य निर्माण और प्रबंधन में गहराई से अध्ययन
आधुनिक सॉफ्टवेयर विकास की दुनिया में, प्रदर्शन सर्वोपरि है। अनुप्रयोगों से हजारों समवर्ती नेटवर्क कनेक्शन, डेटाबेस प्रश्नों और एपीआई कॉलों को बिना किसी परेशानी के संभालने की उम्मीद की जाती है। I/O-बाउंड कार्यों के लिए—जहां प्रोग्राम नेटवर्क या डिस्क जैसे बाहरी संसाधनों की प्रतीक्षा में अपना अधिकांश समय बिताता है—पारंपरिक सिंक्रोनस कोड एक महत्वपूर्ण बाधा बन सकता है। यहीं पर अतुल्यकालिक प्रोग्रामिंग चमकती है, और पायथन का asyncio
पुस्तकालय इस शक्ति को अनलॉक करने की कुंजी है।
asyncio
के समवर्ती मॉडल के केंद्र में एक सरल लेकिन शक्तिशाली अवधारणा निहित है: Task। जबकि कोरौटीन परिभाषित करते हैं कि क्या करना है, कार्य वास्तव में वही करते हैं जो काम करते हैं। वे समवर्ती निष्पादन की मूलभूत इकाई हैं, जो आपके पायथन प्रोग्रामों को एक साथ कई कार्यों को संभालने की अनुमति देते हैं, जिससे थ्रूपुट और प्रतिक्रियाशीलता में नाटकीय रूप से सुधार होता है।
यह व्यापक मार्गदर्शिका आपको asyncio.Task
में गहराई से गोता लगाएगी। हम निर्माण की मूल बातें से लेकर उन्नत प्रबंधन पैटर्न, रद्दीकरण और सर्वोत्तम प्रथाओं तक सब कुछ का पता लगाएंगे। चाहे आप एक उच्च-ट्रैफ़िक वेब सेवा, एक डेटा स्क्रैपिंग टूल या एक वास्तविक समय एप्लिकेशन बना रहे हों, किसी भी आधुनिक पायथन डेवलपर के लिए कार्यों में महारत हासिल करना एक आवश्यक कौशल है।
कोरौटीन क्या है? एक त्वरित पुनश्चर्या
इससे पहले कि हम दौड़ सकें, हमें चलना होगा। और asyncio
की दुनिया में, चलना कोरौटीन को समझना है। एक कोरौटीन async def
के साथ परिभाषित फ़ंक्शन का एक विशेष प्रकार है।
जब आप एक नियमित पायथन फ़ंक्शन को कॉल करते हैं, तो यह शुरू से अंत तक निष्पादित होता है। जब आप एक कोरौटीन फ़ंक्शन को कॉल करते हैं, हालांकि, यह तुरंत निष्पादित नहीं होता है। इसके बजाय, यह एक कोरौटीन ऑब्जेक्ट लौटाता है। यह ऑब्जेक्ट किए जाने वाले काम का एक ब्लूप्रिंट है, लेकिन यह अपने आप में निष्क्रिय है। यह एक रुका हुआ संगणना है जिसे शुरू, निलंबित और फिर से शुरू किया जा सकता है।
import asyncio
async def say_hello(name: str):
print(f"Preparing to greet {name}...")
await asyncio.sleep(1) # Simulate a non-blocking I/O operation
print(f"Hello, {name}!")
# Calling the function doesn't run it, it creates a coroutine object
coro = say_hello("World")
print(f"Created a coroutine object: {coro}")
# To actually run it, you need to use an entry point like asyncio.run()
# asyncio.run(coro)
जादुई कीवर्ड await
है। यह इवेंट लूप को बताता है, "इस ऑपरेशन में कुछ समय लग सकता है, इसलिए यहां मुझे रोकने और किसी और चीज़ पर काम करने के लिए स्वतंत्र महसूस करें। जब यह ऑपरेशन पूरा हो जाए तो मुझे जगाओ।" रोकने और संदर्भों को स्विच करने की यह क्षमता ही समवर्ती को सक्षम बनाती है।
समवर्ती का हृदय: asyncio.Task को समझना
तो, एक कोरौटीन एक ब्लूप्रिंट है। हम रसोई (इवेंट लूप) को खाना बनाना शुरू करने के लिए कैसे कहते हैं? यहीं पर asyncio.Task
काम आता है।
एक asyncio.Task
एक ऑब्जेक्ट है जो एक कोरौटीन को लपेटता है और इसे asyncio इवेंट लूप पर निष्पादन के लिए शेड्यूल करता है। इसे इस तरह समझें:
- कोरौटीन (
async def
): एक डिश के लिए एक विस्तृत नुस्खा। - इवेंट लूप: केंद्रीय रसोई जहां सभी खाना पकाने होते हैं।
await my_coro()
: आप रसोई में खड़े होते हैं और नुस्खा का चरण-दर-चरण पालन करते हैं। जब तक डिश पूरी नहीं हो जाती तब तक आप कुछ और नहीं कर सकते। यह क्रमिक निष्पादन है।asyncio.create_task(my_coro())
: आप नुस्खा रसोई में एक शेफ (कार्य) को सौंपते हैं और कहते हैं, "इस पर काम करना शुरू करें।" शेफ तुरंत शुरू हो जाता है, और आप अन्य चीजें करने के लिए स्वतंत्र हैं, जैसे कि अधिक व्यंजनों को सौंपना। यह समवर्ती निष्पादन है।
मुख्य अंतर यह है कि asyncio.create_task()
कोरौटीन को "पृष्ठभूमि में" चलाने के लिए शेड्यूल करता है और तुरंत आपके कोड को नियंत्रण लौटाता है। आपको एक Task
ऑब्जेक्ट वापस मिलता है, जो इस चल रहे ऑपरेशन के हैंडल के रूप में कार्य करता है। आप इस हैंडल का उपयोग इसकी स्थिति की जांच करने, इसे रद्द करने या बाद में इसके परिणाम की प्रतीक्षा करने के लिए कर सकते हैं।
अपने पहले कार्य बनाना: `asyncio.create_task()` फ़ंक्शन
किसी कार्य को बनाने का प्राथमिक तरीका asyncio.create_task()
फ़ंक्शन के साथ है। यह अपने तर्क के रूप में एक कोरौटीन ऑब्जेक्ट लेता है और इसे निष्पादन के लिए शेड्यूल करता है।
मूल सिंटैक्स
उपयोग सीधा है:
import asyncio
async def my_background_work():
print("Starting background work...")
await asyncio.sleep(2)
print("Background work finished.")
return "Success"
async def main():
print("Main function started.")
# Schedule my_background_work to run concurrently
task = asyncio.create_task(my_background_work())
# While the task runs, we can do other things
print("Task created. Main function continues to run.")
await asyncio.sleep(1)
print("Main function did some other work.")
# Now, wait for the task to complete and get its result
result = await task
print(f"Task completed with result: {result}")
asyncio.run(main())
ध्यान दें कि आउटपुट कैसे दिखाता है कि `main` फ़ंक्शन कार्य बनाने के तुरंत बाद अपना निष्पादन जारी रखता है। यह ब्लॉक नहीं करता है। यह केवल तभी रुकता है जब हम अंत में स्पष्ट रूप से `await task` करते हैं।
एक व्यावहारिक उदाहरण: समवर्ती वेब अनुरोध
आइए एक सामान्य परिदृश्य के साथ कार्यों की वास्तविक शक्ति देखें: कई URL से डेटा प्राप्त करना। इसके लिए, हम लोकप्रिय `aiohttp` लाइब्रेरी का उपयोग करेंगे, जिसे आप `pip install aiohttp` से इंस्टॉल कर सकते हैं।
सबसे पहले, आइए क्रमिक (धीमी) तरीका देखें:
import asyncio
import aiohttp
import time
async def fetch_status(session, url):
async with session.get(url) as response:
return response.status
async def main_sequential():
urls = [
"https://www.python.org",
"https://www.google.com",
"https://www.github.com",
"https://www.microsoft.com"
]
start_time = time.time()
async with aiohttp.ClientSession() as session:
for url in urls:
status = await fetch_status(session, url)
print(f"Status for {url}: {status}")
end_time = time.time()
print(f"Sequential execution took {end_time - start_time:.2f} seconds")
# To run this, you would use: asyncio.run(main_sequential())
यदि प्रत्येक अनुरोध में लगभग 0.5 सेकंड लगते हैं, तो कुल समय लगभग 2 सेकंड होगा, क्योंकि प्रत्येक `await` तब तक लूप को ब्लॉक करता है जब तक कि वह एकल अनुरोध समाप्त न हो जाए।
अब, आइए कार्यों के साथ समवर्ती की शक्ति को उजागर करें:
import asyncio
import aiohttp
import time
# fetch_status coroutine remains the same
async def fetch_status(session, url):
async with session.get(url) as response:
return response.status
async def main_concurrent():
urls = [
"https://www.python.org",
"https://www.google.com",
"https://www.github.com",
"https://www.microsoft.com"
]
start_time = time.time()
async with aiohttp.ClientSession() as session:
# Create a list of tasks, but don't await them yet
tasks = [asyncio.create_task(fetch_status(session, url)) for url in urls]
# Now, wait for all tasks to complete
statuses = await asyncio.gather(*tasks)
for url, status in zip(urls, statuses):
print(f"Status for {url}: {status}")
end_time = time.time()
print(f"Concurrent execution took {end_time - start_time:.2f} seconds")
asyncio.run(main_concurrent())
जब आप समवर्ती संस्करण चलाते हैं, तो आपको एक नाटकीय अंतर दिखाई देगा। कुल समय लगभग सबसे लंबे एकल अनुरोध का समय होगा, न कि उन सभी का योग। ऐसा इसलिए है क्योंकि जैसे ही पहला `fetch_status` कोरौटीन अपने `await session.get(url)` से टकराता है, इवेंट लूप इसे रोक देता है और तुरंत अगला शुरू कर देता है। सभी नेटवर्क अनुरोध प्रभावी रूप से एक ही समय पर होते हैं।
कार्यों के समूह का प्रबंधन: आवश्यक पैटर्न
व्यक्तिगत कार्य बनाना बहुत अच्छा है, लेकिन वास्तविक दुनिया के अनुप्रयोगों में, आपको अक्सर उन्हें लॉन्च करने, प्रबंधित करने और सिंक्रनाइज़ करने की आवश्यकता होती है। `asyncio` इसके लिए कई शक्तिशाली उपकरण प्रदान करता है।
आधुनिक दृष्टिकोण (पायथन 3.11+): `asyncio.TaskGroup`
पायथन 3.11 में पेश किया गया, `TaskGroup` संबंधित कार्यों के समूह को प्रबंधित करने का नया, अनुशंसित और सबसे सुरक्षित तरीका है। यह संरचित समवर्ती प्रदान करता है।
`TaskGroup` की मुख्य विशेषताएं:
- गारंटीड क्लीनअप: `async with` ब्लॉक तब तक बाहर नहीं निकलेगा जब तक कि उसके भीतर बनाए गए सभी कार्य पूरे नहीं हो जाते।
- मजबूत त्रुटि प्रबंधन: यदि समूह के भीतर कोई भी कार्य एक अपवाद उठाता है, तो समूह के अन्य सभी कार्यों को स्वचालित रूप से रद्द कर दिया जाता है, और `async with` ब्लॉक से बाहर निकलने पर अपवाद (या एक `ExceptionGroup`) को फिर से उठाया जाता है। यह अनाथ कार्यों को रोकता है और एक अनुमानित स्थिति सुनिश्चित करता है।
यहां बताया गया है कि इसका उपयोग कैसे करें:
import asyncio
async def worker(delay):
print(f"Worker starting, will sleep for {delay}s")
await asyncio.sleep(delay)
# This worker will fail
if delay == 2:
raise ValueError("Something went wrong in worker 2")
print(f"Worker with delay {delay} finished")
return f"Result from {delay}s"
async def main():
print("Starting main with TaskGroup...")
try:
async with asyncio.TaskGroup() as tg:
task1 = tg.create_task(worker(1))
task2 = tg.create_task(worker(2)) # This one will fail
task3 = tg.create_task(worker(3))
print("Tasks created in the group.")
# This part of the code will NOT be reached if an exception occurs
# The results would be accessed via task1.result(), etc.
print("All tasks completed successfully.")
except* ValueError as eg: # Note the `except*` for ExceptionGroup
print(f"Caught an exception group with {len(eg.exceptions)} exceptions.")
for exc in eg.exceptions:
print(f" - {exc}")
print("Main function finished.")
asyncio.run(main())
जब आप इसे चलाते हैं, तो आप देखेंगे कि `worker(2)` एक त्रुटि उत्पन्न करता है। `TaskGroup` इसे पकड़ता है, अन्य चल रहे कार्यों (जैसे `worker(3)`) को रद्द कर देता है, और फिर एक `ExceptionGroup` उठाता है जिसमें `ValueError` होता है। विश्वसनीय सिस्टम बनाने के लिए यह पैटर्न अविश्वसनीय रूप से मजबूत है।
क्लासिक वर्कहॉर्स: `asyncio.gather()`
`TaskGroup` से पहले, `asyncio.gather()` कई awaitables को समवर्ती रूप से चलाने और उन सभी के समाप्त होने की प्रतीक्षा करने का सबसे आम तरीका था।
gather()
कोरौटीन या कार्यों का एक क्रम लेता है, उन सभी को चलाता है, और इनपुट के समान क्रम में उनके परिणामों की एक सूची लौटाता है। यह सामान्य मामले के लिए एक उच्च-स्तरीय, सुविधाजनक फ़ंक्शन है "इन सभी चीजों को चलाएं और मुझे सभी परिणाम दें।"
import asyncio
async def fetch_data(source, delay):
print(f"Fetching from {source}...")
await asyncio.sleep(delay)
return {"source": source, "data": f"some data from {source}"}
async def main():
# gather can take coroutines directly
results = await asyncio.gather(
fetch_data("API", 2),
fetch_data("Database", 3),
fetch_data("Cache", 1)
)
print(results)
asyncio.run(main())
`gather()` के साथ त्रुटि प्रबंधन: डिफ़ॉल्ट रूप से, यदि `gather()` को पास किए गए awaitables में से कोई भी अपवाद उठाता है, तो `gather()` तुरंत उस अपवाद का प्रचार करता है, और अन्य चल रहे कार्यों को रद्द कर दिया जाता है। आप `return_exceptions=True` के साथ इस व्यवहार को बदल सकते हैं। इस मोड में, अपवाद उठाने के बजाय, इसे संबंधित स्थिति में परिणाम सूची में रखा जाएगा।
# ... inside main()
results = await asyncio.gather(
fetch_data("API", 2),
asyncio.create_task(worker(1)), # This will raise a ValueError
fetch_data("Cache", 1),
return_exceptions=True
)
# results will contain a mix of successful results and exception objects
print(results)
फाइन-ग्रेन्ड कंट्रोल: `asyncio.wait()`
asyncio.wait()` एक निचला-स्तरीय फ़ंक्शन है जो कार्यों के समूह पर अधिक विस्तृत नियंत्रण प्रदान करता है। `gather()` के विपरीत, यह सीधे परिणाम नहीं लौटाता है। इसके बजाय, यह कार्यों के दो सेट लौटाता है: `done` और `pending`।
इसकी सबसे शक्तिशाली विशेषता `return_when` पैरामीटर है, जो हो सकता है:
asyncio.ALL_COMPLETED
(डिफ़ॉल्ट): सभी कार्यों के समाप्त होने पर लौटता है।asyncio.FIRST_COMPLETED
: कम से कम एक कार्य के समाप्त होते ही लौटता है।asyncio.FIRST_EXCEPTION
: जब कोई कार्य अपवाद उठाता है तो लौटता है। यदि कोई कार्य अपवाद नहीं उठाता है, तो यह `ALL_COMPLETED` के बराबर है।
यह कई अनावश्यक डेटा स्रोतों को क्वेरी करने और प्रतिक्रिया देने वाले पहले स्रोत का उपयोग करने जैसे परिदृश्यों के लिए बेहद उपयोगी है:
import asyncio
async def query_source(name, delay):
await asyncio.sleep(delay)
return f"Result from {name}"
async def main():
tasks = [
asyncio.create_task(query_source("Fast Mirror", 0.5)),
asyncio.create_task(query_source("Slow Main DB", 2.0)),
asyncio.create_task(query_source("Geographic Replica", 0.8))
]
done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
# Get the result from the completed task
first_result = done.pop().result()
print(f"Got first result: {first_result}")
# We now have pending tasks that are still running. It's crucial to clean them up!
print(f"Cancelling {len(pending)} pending tasks...")
for task in pending:
task.cancel()
# Await the cancelled tasks to allow them to process the cancellation
await asyncio.gather(*pending, return_exceptions=True)
print("Cleanup complete.")
asyncio.run(main())
TaskGroup बनाम gather() बनाम wait(): किसका उपयोग कब करें?
- `asyncio.TaskGroup` (पायथन 3.11+) को अपनी डिफ़ॉल्ट पसंद के रूप में उपयोग करें। इसका संरचित समवर्ती मॉडल एक तार्किक ऑपरेशन से संबंधित कार्यों के समूह को प्रबंधित करने के लिए सुरक्षित, स्वच्छ और कम त्रुटि-प्रवण है।
- `asyncio.gather()` का उपयोग तब करें जब आपको स्वतंत्र कार्यों के समूह को चलाने की आवश्यकता हो और आप बस उनके परिणामों की सूची चाहते हों। यह अभी भी बहुत उपयोगी है और सरल मामलों के लिए थोड़ा अधिक संक्षिप्त है, खासकर पायथन संस्करणों में 3.11 से पहले।
- `asyncio.wait()` का उपयोग उन्नत परिदृश्यों के लिए करें जहां आपको पूर्णता स्थितियों (जैसे, पहले परिणाम की प्रतीक्षा करना) पर बढ़िया नियंत्रण की आवश्यकता होती है और आप शेष लंबित कार्यों को मैन्युअल रूप से प्रबंधित करने के लिए तैयार हैं।
कार्य जीवनचक्र और प्रबंधन
एक बार एक कार्य बन जाने के बाद, आप `Task` ऑब्जेक्ट पर विधियों का उपयोग करके इसके साथ इंटरैक्ट कर सकते हैं।
कार्य स्थिति की जांच करना
task.done()
: यदि कार्य पूरा हो गया है (या तो सफलतापूर्वक, एक अपवाद के साथ, या रद्दीकरण द्वारा) तो `True` लौटाता है।task.cancelled()
: यदि कार्य रद्द कर दिया गया था तो `True` लौटाता है।task.exception()
: यदि कार्य ने एक अपवाद उठाया, तो यह अपवाद ऑब्जेक्ट लौटाता है। अन्यथा, यह `None` लौटाता है। आप इसे केवल तभी कॉल कर सकते हैं जब कार्य `done()` हो।
परिणाम प्राप्त करना
किसी कार्य का परिणाम प्राप्त करने का मुख्य तरीका बस `await task` है। यदि कार्य सफलतापूर्वक समाप्त हो गया, तो यह मान लौटाता है। यदि इसने एक अपवाद उठाया, तो `await task` उस अपवाद को फिर से उठाएगा। यदि इसे रद्द कर दिया गया था, तो `await task` एक `CancelledError` उठाएगा।
वैकल्पिक रूप से, यदि आप जानते हैं कि कोई कार्य `done()` है, तो आप `task.result()` को कॉल कर सकते हैं। यह मान लौटाने या अपवाद उठाने के मामले में `await task` के समान व्यवहार करता है।
रद्दीकरण की कला
मजबूत एप्लिकेशन बनाने के लिए लंबे समय तक चलने वाले कार्यों को शालीनता से रद्द करने में सक्षम होना महत्वपूर्ण है। आपको समय सीमा, उपयोगकर्ता अनुरोध या सिस्टम में कहीं और त्रुटि के कारण किसी कार्य को रद्द करने की आवश्यकता हो सकती है।
आप इसके task.cancel()` विधि को कॉल करके किसी कार्य को रद्द करते हैं। हालांकि, यह तुरंत कार्य को नहीं रोकता है। इसके बजाय, यह अगले
await
बिंदु पर कोरौटीन के अंदर फेंकने के लिए एक `CancelledError` अपवाद शेड्यूल करता है। यह एक महत्वपूर्ण विवरण है। यह कोरौटीन को बाहर निकलने से पहले साफ करने का मौका देता है।
एक अच्छी तरह से व्यवहार करने वाले कोरौटीन को इस `CancelledError` को शालीनता से संभालना चाहिए, आमतौर पर यह सुनिश्चित करने के लिए `try...finally` ब्लॉक का उपयोग करना चाहिए कि फ़ाइल हैंडल या डेटाबेस कनेक्शन जैसे संसाधनों को बंद कर दिया जाए।
import asyncio
async def resource_intensive_task():
print("Acquiring resource (e.g., opening a connection)...")
try:
for i in range(10):
print(f"Working... step {i+1}")
await asyncio.sleep(1) # This is an await point where CancelledError can be injected
except asyncio.CancelledError:
print("Task was cancelled! Cleaning up...")
raise # It's good practice to re-raise CancelledError
finally:
print("Releasing resource (e.g., closing connection). This always runs.")
async def main():
task = asyncio.create_task(resource_intensive_task())
# Let it run for a bit
await asyncio.sleep(2.5)
print("Main decides to cancel the task.")
task.cancel()
try:
await task
except asyncio.CancelledError:
print("Main has confirmed the task was cancelled.")
asyncio.run(main())
`finally` ब्लॉक को निष्पादित करने की गारंटी है, जिससे यह सफाई तर्क के लिए सही जगह बन जाती है।
`asyncio.timeout()` और `asyncio.wait_for()` के साथ टाइमआउट जोड़ना
मैन्युअल रूप से सोना और रद्द करना थकाऊ है। `asyncio` इस सामान्य पैटर्न के लिए सहायक प्रदान करता है।
पायथन 3.11+ में, `asyncio.timeout()` संदर्भ प्रबंधक पसंदीदा तरीका है:
async def long_running_operation():
await asyncio.sleep(10)
print("Operation finished")
async def main():
try:
async with asyncio.timeout(2): # Set a 2-second timeout
await long_running_operation()
except TimeoutError:
print("The operation timed out!")
asyncio.run(main())
पुराने पायथन संस्करणों के लिए, आप `asyncio.wait_for()` का उपयोग कर सकते हैं। यह समान रूप से काम करता है लेकिन एक फ़ंक्शन कॉल में awaitable को लपेटता है:
async def main_legacy():
try:
await asyncio.wait_for(long_running_operation(), timeout=2)
except asyncio.TimeoutError:
print("The operation timed out!")
asyncio.run(main_legacy())
दोनों उपकरण समय सीमा तक पहुंचने पर आंतरिक कार्य को रद्द करके काम करते हैं, जिससे `TimeoutError` उत्पन्न होता है (जो `CancelledError` का उपवर्ग है)।
सामान्य कमियां और सर्वोत्तम अभ्यास
कार्यों के साथ काम करना शक्तिशाली है, लेकिन बचने के लिए कुछ सामान्य जाल हैं।
- कमी: "फायर एंड फॉरगेट" गलती। `create_task` के साथ एक कार्य बनाना और फिर कभी उसका इंतजार नहीं करना (या `TaskGroup` जैसा प्रबंधक) खतरनाक है। यदि वह कार्य एक अपवाद उठाता है, तो अपवाद चुपचाप खो सकता है, और आपका प्रोग्राम कार्य पूरा करने से पहले ही बाहर निकल सकता है। हमेशा प्रत्येक कार्य के लिए एक स्पष्ट स्वामी रखें जो उसके परिणाम की प्रतीक्षा करने के लिए जिम्मेदार हो।
- कमी: `asyncio.run()` को `create_task()` के साथ भ्रमित करना। `asyncio.run(my_coro())` एक `asyncio` प्रोग्राम शुरू करने का मुख्य प्रवेश बिंदु है। यह एक नया इवेंट लूप बनाता है और दिए गए कोरौटीन को तब तक चलाता है जब तक कि वह पूरा नहीं हो जाता। `asyncio.create_task(my_coro())` का उपयोग समवर्ती निष्पादन को शेड्यूल करने के लिए पहले से चल रहे एसिंक्रोनस फ़ंक्शन के अंदर किया जाता है।
- सर्वोत्तम अभ्यास: आधुनिक पायथन के लिए `TaskGroup` का उपयोग करें। इसका डिज़ाइन कई सामान्य त्रुटियों को रोकता है, जैसे भूले हुए कार्य और बिना संभाले गए अपवाद। यदि आप पायथन 3.11 या बाद के संस्करण पर हैं, तो इसे अपनी डिफ़ॉल्ट पसंद बनाएं।
- सर्वोत्तम अभ्यास: अपने कार्यों को नाम दें। कार्य बनाते समय, `name` पैरामीटर का उपयोग करें: `asyncio.create_task(my_coro(), name='DataProcessor-123')`। यह डीबगिंग के लिए अमूल्य है। जब आप सभी चल रहे कार्यों को सूचीबद्ध करते हैं, तो सार्थक नाम होने से आपको यह समझने में मदद मिलती है कि आपका प्रोग्राम क्या कर रहा है।
- सर्वोत्तम अभ्यास: शालीनतापूर्ण शटडाउन सुनिश्चित करें। जब आपके एप्लिकेशन को बंद करने की आवश्यकता हो, तो सुनिश्चित करें कि आपके पास सभी चल रहे पृष्ठभूमि कार्यों को रद्द करने और उन्हें ठीक से साफ करने की प्रतीक्षा करने के लिए एक तंत्र है।
उन्नत अवधारणाएं: परे एक झलक
डीबगिंग और आत्मनिरीक्षण के लिए, `asyncio` कुछ उपयोगी फ़ंक्शन प्रदान करता है:
asyncio.current_task()
: वर्तमान में निष्पादित हो रहे कोड के लिए `Task` ऑब्जेक्ट लौटाता है।asyncio.all_tasks()
: इवेंट लूप द्वारा वर्तमान में प्रबंधित किए जा रहे सभी `Task` ऑब्जेक्ट का एक सेट लौटाता है। यह यह देखने के लिए डीबगिंग के लिए बहुत अच्छा है कि क्या चल रहा है।
आप `task.add_done_callback()` का उपयोग करके कार्यों के लिए पूर्णता कॉलबैक भी संलग्न कर सकते हैं। जबकि यह उपयोगी हो सकता है, इससे अक्सर एक अधिक जटिल, कॉलबैक-शैली कोड संरचना होती है। `await`, `TaskGroup` या `gather` का उपयोग करने वाले आधुनिक दृष्टिकोण आम तौर पर पठनीयता और रखरखाव के लिए पसंद किए जाते हैं।
निष्कर्ष
`asyncio.Task` आधुनिक पायथन में समवर्ती का इंजन है। कार्यों के जीवनचक्र को बनाने, प्रबंधित करने और शालीनता से संभालने के तरीके को समझकर, आप अपने I/O-बाउंड अनुप्रयोगों को धीमे, क्रमिक प्रक्रियाओं से अत्यधिक कुशल, स्केलेबल और प्रतिक्रियाशील प्रणालियों में बदल सकते हैं।
हमने `create_task()` के साथ एक कोरौटीन को शेड्यूल करने की मूलभूत अवधारणा से लेकर `TaskGroup`, `gather()` और `wait()` के साथ जटिल वर्कफ़्लो को व्यवस्थित करने की यात्रा को कवर किया है। हमने लचीला सॉफ़्टवेयर बनाने के लिए मजबूत त्रुटि प्रबंधन, रद्दीकरण और टाइमआउट के महत्वपूर्ण महत्व का भी पता लगाया है।
अतुल्यकालिक प्रोग्रामिंग की दुनिया विशाल है, लेकिन कार्यों में महारत हासिल करना सबसे महत्वपूर्ण कदम है जो आप उठा सकते हैं। प्रयोग करना शुरू करें। अपने एप्लिकेशन के एक क्रमिक, I/O-बाउंड भाग को समवर्ती कार्यों का उपयोग करने के लिए रूपांतरित करें और स्वयं प्रदर्शन लाभों को देखें। समवर्ती की शक्ति को अपनाएं, और आप उच्च-प्रदर्शन पायथन एप्लिकेशन की अगली पीढ़ी बनाने के लिए अच्छी तरह से सुसज्जित होंगे।