Python'da bir vaqtda bajariladigan dasturlash kuchini oching. Yuqori samarali, masshtablanuvchi ilovalar uchun Asyncio vazifalarini yaratish, boshqarish va bekor qilishni o'rganing.
Python Asyncio'ni o'zlashtirish: Vazifalarni yaratish va boshqarishga chuqur sho'ng'ish
Zamonaviy dasturiy ta'minotni ishlab chiqish dunyosida unumdorlik juda muhimdir. Ilovalar minglab bir vaqtda bajariladigan tarmoq ulanishlari, ma'lumotlar bazasi so'rovlari va API chaqiruvlarini hech qanday qiyinchiliksiz boshqara olishi, javob beruvchan bo'lishi kutiladi. Dastur o'z vaqtining ko'p qismini tarmoq yoki disk kabi tashqi resurslarni kutish bilan o'tkazadigan K/CH-ga bog'liq operatsiyalar uchun an'anaviy sinxron kod jiddiy tiqilishga aylanishi mumkin. Aynan shu yerda asinxron dasturlash o'zini ko'rsatadi va Python'ning asyncio
kutubxonasi bu kuchni ochishning kalitidir.
asyncio
'ning konkurentlik modelining markazida oddiy, ammo kuchli tushuncha yotadi: Vazifa. Koroutinlar nima qilishni belgilasa, Vazifalar aslida ishlarni bajaradi. Ular bir vaqtda bajarilishning asosiy birligi bo'lib, Python dasturlaringizga bir nechta operatsiyalarni bir vaqtda bajarish imkonini beradi, bu esa o'tkazuvchanlik va javob beruvchanlikni sezilarli darajada yaxshilaydi.
Ushbu keng qamrovli qo'llanma sizni asyncio.Task
-ga chuqur sho'ng'ishga olib boradi. Biz yaratish asoslaridan tortib, ilg'or boshqaruv usullari, bekor qilish va eng yaxshi amaliyotlargacha hamma narsani ko'rib chiqamiz. Siz yuqori trafikli veb-xizmat, ma'lumotlarni qirib olish vositasi yoki real vaqt rejimida ishlaydigan ilova yaratayotgan bo'lsangiz ham, Vazifalarni o'zlashtirish har qanday zamonaviy Python dasturchisi uchun muhim ko'nikmadir.
Koroutin nima? Tezkor eslatma
Yugurishdan oldin, biz yurishimiz kerak. Va asyncio
dunyosida yurish koroutinlarni tushunishdir. Koroutin async def
bilan belgilangan funksiyaning maxsus turidir.
Oddiy Python funksiyasini chaqirganingizda, u boshidan oxirigacha bajariladi. Koroutin funksiyasini chaqirganingizda esa, u darhol ishga tushmaydi. Buning o'rniga, u koroutin ob'ektini qaytaradi. Bu ob'ekt bajarilishi kerak bo'lgan ish uchun reja bo'lib, lekin o'zi faol emas. Bu to'xtatilgan hisoblash bo'lib, uni boshlash, to'xtatib turish va davom ettirish mumkin.
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)
Sehrli kalit so'z await
. U hodisalar sikliga shunday deydi: "Bu operatsiya biroz vaqt olishi mumkin, shuning uchun meni shu yerda to'xtatib turing va boshqa ish bilan shug'ullaning. Bu operatsiya tugaganda meni uyg'oting." Konkurentlikni aynan shu to'xtatib turish va kontekstlarni almashtirish qobiliyati ta'minlaydi.
Konkurentlikning yuragi: asyncio.Task'ni tushunish
Demak, koroutin bu reja. Oshxonaga (hodisalar sikliga) qanday qilib ovqat pishirishni boshlashni aytamiz? Bu yerda asyncio.Task
ishga tushadi.
asyncio.Task
bu koroutinni o'rab oluvchi va uni asyncio hodisalar siklida bajarish uchun rejalashtiruvchi ob'ektdir. Buni quyidagicha tasavvur qiling:
- Koroutin (
async def
): Taom uchun batafsil retsept. - Hodisalar Sikli: Barcha pishirish ishlari bajariladigan markaziy oshxona.
await my_coro()
: Siz oshxonada turib, retseptni o'zingiz bosqichma-bosqich bajarasiz. Taom tugaguncha boshqa hech narsa qila olmaysiz. Bu ketma-ket bajarilish.asyncio.create_task(my_coro())
: Siz retseptni oshxonadagi oshpazga (Vazifaga) berasiz va "Buni bajarishni boshlang" deysiz. Oshpaz darhol boshlaydi va siz boshqa narsalar bilan, masalan, ko'proq retseptlarni tarqatish bilan shug'ullanishingiz mumkin. Bu bir vaqtda bajarilish.
Asosiy farq shundaki, asyncio.create_task()
koroutinni "fondda" ishlash uchun rejalashtiradi va boshqaruvni darhol sizning kodingizga qaytaradi. Siz ushbu davom etayotgan operatsiyaga tutqich vazifasini bajaradigan Task
ob'ektini olasiz. Siz bu tutqichdan uning holatini tekshirish, uni bekor qilish yoki keyinroq natijasini kutish uchun foydalanishingiz mumkin.
Birinchi Vazifalaringizni yaratish: `asyncio.create_task()` funksiyasi
Vazifa yaratishning asosiy usuli asyncio.create_task()
funksiyasidan foydalanishdir. U koroutin ob'ektini argument sifatida oladi va uni bajarish uchun rejalashtiradi.
Asosiy sintaksis
Foydalanish oddiy:
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())
Chiqishdagi `main` funksiyasi vazifani yaratgandan so'ng darhol o'z ishini davom ettirayotganiga e'tibor bering. U bloklamaydi. U faqat oxirida `await task` ni aniq ko'rsatganimizda to'xtaydi.
Amaliy misol: Bir vaqtda veb-so'rovlar
Keling, Vazifalarning haqiqiy kuchini umumiy ssenariy yordamida ko'rib chiqamiz: bir nechta URL'lardan ma'lumot olish. Buning uchun biz `pip install aiohttp` orqali o'rnatishingiz mumkin bo'lgan mashhur `aiohttp` kutubxonasidan foydalanamiz.
Avval, ketma-ket (sekin) usulni ko'rib chiqaylik:
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())
Agar har bir so'rov taxminan 0,5 soniya davom etsa, umumiy vaqt taxminan 2 soniya bo'ladi, chunki har bir `await` hodisalar siklini o'sha bitta so'rov tugaguncha bloklaydi.
Endi Vazifalar yordamida konkurentlik kuchini ishga solamiz:
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())
Bir vaqtda ishlaydigan versiyani ishga tushirganingizda, sezilarli farqni ko'rasiz. Umumiy vaqt barcha so'rovlarning yig'indisi emas, balki eng uzoq bitta so'rov vaqtiga teng bo'ladi. Buning sababi, birinchi `fetch_status` koroutini `await session.get(url)` ga yetishi bilanoq, hodisalar sikli uni to'xtatadi va darhol keyingisini boshlaydi. Barcha tarmoq so'rovlari samarali ravishda bir vaqtda sodir bo'ladi.
Vazifalar guruhini boshqarish: Asosiy usullar
Alohida vazifalarni yaratish yaxshi, ammo real ilovalarda siz ko'pincha ularning butun guruhini ishga tushirishingiz, boshqarishingiz va sinxronlashingiz kerak bo'ladi. `asyncio` buning uchun bir nechta kuchli vositalarni taqdim etadi.
Zamonaviy yondashuv (Python 3.11+): `asyncio.TaskGroup`
Python 3.11 da kiritilgan `TaskGroup` bog'liq vazifalar guruhini boshqarishning yangi, tavsiya etilgan va eng xavfsiz usulidir. U tuzilgan konkurentlik deb nomlanuvchi narsani ta'minlaydi.
`TaskGroup` ning asosiy xususiyatlari:
- Kafolatlangan tozalash: `async with` bloki ichida yaratilgan barcha vazifalar tugallanmaguncha, u chiqmaydi.
- Kuchli xatolarni boshqarish: Agar guruhdagi biron bir vazifa istisno (exception) ko'tarsa, guruhdagi barcha boshqa vazifalar avtomatik ravishda bekor qilinadi va istisno (yoki `ExceptionGroup`) `async with` blokidan chiqishda qayta ko'tariladi. Bu yetim qolgan vazifalarni oldini oladi va oldindan aytib bo'ladigan holatni ta'minlaydi.
Uni qanday ishlatish quyida keltirilgan:
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())
Buni ishga tushirganingizda, `worker(2)` xato yuzaga keltirganini ko'rasiz. `TaskGroup` buni ushlaydi, boshqa ishlayotgan vazifalarni (`worker(3)` kabi) bekor qiladi va keyin `ValueError` ni o'z ichiga olgan `ExceptionGroup` ni ko'taradi. Bu usul ishonchli tizimlarni qurish uchun nihoyatda mustahkamdir.
Klassik ishchi ot: `asyncio.gather()`
`TaskGroup` dan oldin, `asyncio.gather()` bir nechta awaitable-larni bir vaqtda bajarish va ularning barchasi tugashini kutishning eng keng tarqalgan usuli edi.
gather()
koroutinlar yoki Vazifalar ketma-ketligini qabul qiladi, ularning barchasini bajaradi va kirishlar bilan bir xil tartibda ularning natijalari ro'yxatini qaytaradi. Bu "barcha shu narsalarni bajaring va menga barcha natijalarni bering" degan umumiy holat uchun yuqori darajadagi, qulay funksiyadir.
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()` bilan xatolarni boshqarish: Odatiy bo'lib, agar `gather()` ga berilgan awaitable'lardan biron biri istisno ko'tarsa, `gather()` bu istisnoni darhol tarqatadi va boshqa ishlayotgan vazifalar bekor qilinadi. Siz bu xatti-harakatni `return_exceptions=True` bilan o'zgartirishingiz mumkin. Bu rejimda, istisno ko'tarish o'rniga, u natijalar ro'yxatiga tegishli joyga joylashtiriladi.
# ... 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)
Nozik nazorat: `asyncio.wait()`
asyncio.wait()
vazifalar guruhi ustidan batafsilroq nazoratni taklif qiluvchi pastroq darajadagi funksiyadir. `gather()` dan farqli o'laroq, u natijalarni to'g'ridan-to'g'ri qaytarmaydi. Buning o'rniga, u ikkita vazifalar to'plamini qaytaradi: `done` (bajarilgan) va `pending` (kutilayotgan).
Uning eng kuchli xususiyati `return_when` parametri bo'lib, u quyidagicha bo'lishi mumkin:
asyncio.ALL_COMPLETED
(standart): Barcha vazifalar tugagandan so'ng qaytaradi.asyncio.FIRST_COMPLETED
: Kamida bitta vazifa tugashi bilanoq qaytaradi.asyncio.FIRST_EXCEPTION
: Vazifa istisno ko'targanda qaytaradi. Agar hech qanday vazifa istisno ko'tarmasa, u `ALL_COMPLETED` ga teng.
Bu bir nechta ortiqcha ma'lumot manbalarini so'rash va birinchi javob berganidan foydalanish kabi stsenariylar uchun juda foydalidir:
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 vs. gather() vs. wait(): Qaysi birini qachon ishlatish kerak?
- `asyncio.TaskGroup` (Python 3.11+) ni odatiy tanlovingiz sifatida ishlating. Uning tuzilgan konkurentlik modeli bir butun mantiqiy operatsiyaga tegishli vazifalar guruhini boshqarish uchun xavfsizroq, tozarog' va kamroq xatolarga moyil.
- `asyncio.gather()` dan foydalaning, agar siz mustaqil vazifalar guruhini ishga tushirishingiz va shunchaki ularning natijalari ro'yxatini olishni istasangiz. U hali ham juda foydali va oddiy holatlar uchun, ayniqsa Python 3.11 dan oldingi versiyalarida, biroz qisqaroq.
- `asyncio.wait()` dan foydalaning, agar siz yakunlash shartlari (masalan, birinchi natijani kutish) ustidan nozik nazoratni talab qiladigan va qolgan kutilayotgan vazifalarni qo'lda boshqarishga tayyor bo'lgan ilg'or stsenariylar uchun.
Vazifa hayot sikli va boshqaruvi
Vazifa yaratilgandan so'ng, siz u bilan `Task` ob'ektidagi usullar yordamida o'zaro aloqada bo'lishingiz mumkin.
Vazifa holatini tekshirish
task.done()
: Vazifa tugallangan bo'lsa (`muvaffaqiyatli, istisno bilan yoki bekor qilingan holda`), `True` qiymatini qaytaradi.task.cancelled()
: Vazifa bekor qilingan bo'lsa, `True` qiymatini qaytaradi.task.exception()
: Agar vazifa istisno ko'targan bo'lsa, bu istisno ob'ektini qaytaradi. Aks holda, `None` qaytaradi. Buni faqat vazifa `done()` bo'lgandan keyin chaqirishingiz mumkin.
Natijalarni olish
Vazifaning natijasini olishning asosiy usuli oddiygina `await task` qilishdir. Agar vazifa muvaffaqiyatli tugagan bo'lsa, bu qiymatni qaytaradi. Agar u istisno ko'targan bo'lsa, `await task` bu istisnoni qayta ko'taradi. Agar u bekor qilingan bo'lsa, `await task` `CancelledError` ni ko'taradi.
Muqobil ravishda, agar vazifaning `done()` ekanligini bilsangiz, `task.result()` ni chaqirishingiz mumkin. Bu qiymatlarni qaytarish yoki istisnolarni ko'tarish nuqtai nazaridan `await task` bilan bir xil ishlaydi.
Bekor qilish san'ati
Uzoq davom etadigan operatsiyalarni muloyimlik bilan bekor qila olish mustahkam ilovalar yaratish uchun juda muhimdir. Siz vazifani vaqt tugashi, foydalanuvchi so'rovi yoki tizimdagi boshqa xato tufayli bekor qilishingiz mumkin.
Vazifani uning task.cancel()
usulini chaqirish orqali bekor qilasiz. Biroq, bu vazifani darhol to'xtatmaydi. Buning o'rniga, u keyingi await
nuqtasida koroutin ichida `CancelledError` istisnosini ko'tarishni rejalashtiradi. Bu juda muhim tafsilot. Bu koroutinga chiqishdan oldin tozalash imkoniyatini beradi.
Yaxshi ishlaydigan koroutin bu `CancelledError` ni muloyimlik bilan boshqarishi kerak, odatda fayl deskriptorlari yoki ma'lumotlar bazasi ulanishlari kabi resurslar yopilishini ta'minlash uchun `try...finally` blokidan foydalaniladi.
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())
The `finally` bloki bajarilishi kafolatlanadi, bu esa uni tozalash mantiqi uchun eng zo'r joyga aylantiradi.
`asyncio.timeout()` va `asyncio.wait_for()` yordamida vaqt chegaralarini qo'shish
Qo'lda uxlash va bekor qilish zerikarli. `asyncio` bu umumiy usul uchun yordamchilarni taqdim etadi.
Python 3.11+ da `asyncio.timeout()` kontekst menejeri afzalroq usul hisoblanadi:
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())
Eskiroq Python versiyalari uchun siz `asyncio.wait_for()` dan foydalanishingiz mumkin. U shunga o'xshash ishlaydi, ammo awaitable'ni funksiya chaqiruviga o'raydi:
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())
Ikkala vosita ham vaqt chegarasiga yetganda ichki vazifani bekor qilish orqali ishlaydi, bu esa `TimeoutError` (u `CancelledError` ning quyi sinfi) ni ko'taradi.
Umumiy kamchiliklar va eng yaxshi amaliyotlar
Vazifalar bilan ishlash kuchli, ammo oldini olish kerak bo'lgan bir nechta umumiy tuzoqlar mavjud.
- Kamchilik: "Ishga tushirish va unutish" xatosi. `create_task` bilan vazifa yaratish va keyin uni hech qachon kutmaslik (`TaskGroup` kabi boshqaruvchini ham) xavflidir. Agar bu vazifa istisno ko'tarsa, istisno jimlikda yo'qolishi mumkin va dasturingiz vazifa o'z ishini tugatmasdan oldin chiqib ketishi mumkin. Har bir vazifa uchun uning natijasini kutish uchun mas'ul bo'lgan aniq egasini belgilang.
- Kamchilik: `asyncio.run()` ni `create_task()` bilan aralashtirish. `asyncio.run(my_coro())` bu `asyncio` dasturini boshlash uchun asosiy kirish nuqtasidir. U yangi hodisalar siklini yaratadi va berilgan koroutinni tugagunicha ishga tushiradi. `asyncio.create_task(my_coro())` esa allaqachon ishlayotgan asinxron funksiya ichida bir vaqtda bajarilishni rejalashtirish uchun ishlatiladi.
- Eng yaxshi amaliyot: Zamonaviy Python uchun `TaskGroup` dan foydalaning. Uning dizayni ko'plab umumiy xatolarni, masalan, unutilgan vazifalar va ishlov berilmagan istisnolarni oldini oladi. Agar siz Python 3.11 yoki undan keyingi versiyalardan foydalanayotgan bo'lsangiz, uni odatiy tanlovingizga aylantiring.
- Eng yaxshi amaliyot: Vazifalaringizga nom bering. Vazifa yaratayotganda `name` parametridan foydalaning: `asyncio.create_task(my_coro(), name='DataProcessor-123')`. Bu disk raskadrovka qilish uchun juda qimmatlidir. Barcha ishlayotgan vazifalarni ro'yxatga olganingizda, ma'noli nomlar dasturingiz nima qilayotganini tushunishga yordam beradi.
- Eng yaxshi amaliyot: Muloqotli o'chirishni ta'minlash. Ilovangizni o'chirish kerak bo'lganda, barcha ishlayotgan fon vazifalarini bekor qilish va ularning to'g'ri tozalanishini kutish mexanizmiga ega ekanligingizga ishonch hosil qiling.
Ilg'or tushunchalar: Kengroq nazar
Disk raskadrovka va introspeksiya uchun `asyncio` bir nechta foydali funksiyalarni taqdim etadi:
asyncio.current_task()
: Hozirda bajarilayotgan kod uchun `Task` ob'ektini qaytaradi.asyncio.all_tasks()
: Hodisalar sikli tomonidan boshqarilayotgan barcha `Task` ob'ektlarining to'plamini qaytaradi. Bu nima ishlayotganini ko'rish uchun disk raskadrovka qilishda juda yaxshi.
Shuningdek, `task.add_done_callback()` yordamida vazifalarga bajarish callback'larini biriktirishingiz mumkin. Bu foydali bo'lishi mumkin bo'lsa-da, ko'pincha murakkabroq, callback uslubidagi kod tuzilishiga olib keladi. `await`, `TaskGroup` yoki `gather` dan foydalanadigan zamonaviy yondashuvlar odatda o'qish qulayligi va parvarishlash uchun afzal ko'riladi.
Xulosa
asyncio.Task
zamonaviy Python'dagi konkurentlik dvigateli hisoblanadi. Vazifalarni qanday yaratish, boshqarish va ularning hayot siklini muloyimlik bilan boshqarishni tushunib, siz o'zingizning K/CH-ga bog'liq ilovalaringizni sekin, ketma-ket jarayonlardan yuqori samarali, masshtablanuvchi va javob beruvchan tizimlarga aylantirishingiz mumkin.
Biz `create_task()` bilan koroutinni rejalashtirishning asosiy tushunchasidan tortib, `TaskGroup`, `gather()` va `wait()` yordamida murakkab ish jarayonlarini tashkil qilishgacha bo'lgan yo'lni qamrab oldik. Shuningdek, chidamli dasturiy ta'minotni yaratish uchun mustahkam xatolarni boshqarish, bekor qilish va vaqt chegaralarining muhimligini o'rganib chiqdik.
Asinxron dasturlash dunyosi juda keng, ammo Vazifalarni o'zlashtirish siz qila oladigan eng muhim qadamdir. Tajriba qilishni boshlang. Ilovangizning ketma-ket, K/CH-ga bog'liq qismini bir vaqtda ishlaydigan vazifalardan foydalanishga aylantiring va ishlashdagi yutuqlarga o'zingiz guvoh bo'ling. Konkurentlik kuchini qabul qiling va siz yuqori samarali Python ilovalarining keyingi avlodini qurish uchun yaxshi jihozlangan bo'lasiz.