Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Nega async (I/O-bog'liq)
- 2.2. Concurrency vs parallelism
- 2.3. Event loop (hodisalar sikli)
- 2.4. I/O-bog'liq vs CPU-bog'liq
- 2.5. Async naqshlar (gather, semaphore)
- 2.6. Async cheklovlari va tuzoqlar
- 2.7. Async va boshqa miqyoslash
- 2.8. Async — resursni samarali ishlatish
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Sinxron vs async (kutish vaqti)
- Misol 2 — Event loop (navbat bilan boshqarish)
- Misol 3 — I/O-bog'liq vs CPU-bog'liq
- Misol 4 — Semaphore (concurrency cheklash)
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
29.8-dars: Katta hajmdagi async
29-QISM — MIQYOS VA UNUMDORLIK · 8-dars
1. Kirish va motivatsiya
Serverga bir vaqtda 10,000 foydalanuvchi ulansa — har biriga alohida ip (thread) yoki jarayon (process) ajratish qimmat (xotira, kontekst almashinuvi). Ko'p ulanish kutadi (I/O — baza javobi, tashqi API, fayl) — kutish paytida ip bo'sh turadi (behuda resurs). An'anaviy "har ulanishga bir ip" modeli minglab ulanishga miqyoslanmaydi. Asinxron (async) dasturlash (14-qism) buni hal qiladi: bir ip ko'p ulanishni boshqaradi — biri kutganda (I/O) boshqasiga o'tadi (kutishni bloklamasdan). Bu I/O-bog'liq yuklar (veb server, API) uchun juda samarali: kam resurs bilan ko'p ulanish.
Katta hajmdagi async — minglab bir vaqtda ulanishni asinxron kod bilan boshqarish: asyncio (14-qism — Python async), event loop (hodisalar sikli — vazifalarni navbat bilan), coroutine (async def — to'xtatiladigan funksiya), concurrency vs parallelism (bir vaqtda boshqarish vs bir vaqtda bajarish), I/O-bog'liq vs CPU-bog'liq (async I/O uchun, CPU uchun emas). Foydalar: ko'p ulanish (bir ip — minglab), kam resurs (ip/jarayon emas), samarali kutish (I/O paytida boshqa ish). Bu 14-qism (async asoslari), 20-qism (FastAPI — async) ni miqyos darajasiga ko'taradi. Async — kam resurs bilan ko'p ulanish. I/O kutish — samarali.
Real vaziyat. Bir API tashqi xizmatlarga ko'p so'rov yuborardi (har foydalanuvchi so'rovi uchun 5 tashqi API) — sinxron kodda har so'rov ketma-ket kutilardi (5 × 200ms = 1s). Async qo'llanildi (14-qism — asyncio.gather): 5 so'rov parallel yuborildi (kutish paytida boshqasi — 200ms hammasi). API 5 barobar tez bo'ldi. Va bir server minglab ulanishni ko'tardi (async — kam resurs). Async — I/O kutishni samarali qildi.
Bu darsda katta hajmdagi async ni o'rganamiz.
Bu darsda:
- Nega async (I/O-bog'liq)
- Concurrency vs parallelism
- Event loop (hodisalar sikli)
- I/O-bog'liq vs CPU-bog'liq
- Async naqshlar (gather, semaphore)
- Async cheklovlari va tuzoqlar
- Async va boshqa miqyoslash
- Amaliy: async concurrency modeli
ℹ Async 14-qismda o'rganilgan; misollar concurrency mantiqini (deterministik) modellashtiradi.
2. Nazariya — chuqur tushuntirish
2.1. Nega async (I/O-bog'liq)
Kutish paytida boshqa ish:
Sinxron: har so'rov ketma-ket kutadi (I/O — bo'sh turish)
so'rov1 (kut 200ms) → so'rov2 (kut 200ms) = 400ms
Async: kutish paytida boshqasiga o'tadi (parallel kutish)
so'rov1, so'rov2 birga kutadi = 200msNega async — ko'p ish I/O-bog'liq (baza, tashqi API, fayl — kutish, hisoblash emas) — kutish paytida resurs bo'sh turadi (sinxron — ip kutadi, ish yo'q); async kutish paytida boshqa ishga o'tadi (bloklamasdan). Sabab: I/O sekin (tarmoq, disk — millisekundlar), lekin CPU emas (kutish) — bu vaqtni boshqa ishga ishlatish (bir ip ko'p ulanishni). Foyda: ko'p ulanish (bir ip — minglab), kam resurs (ip/jarayon emas). Bu 14-qism (async) ning miqyos qiymati. Async — kutishni samarali qilish (I/O uchun). Kutish paytida — boshqa ish.
2.2. Concurrency vs parallelism
Ikki xil "bir vaqtda":
CONCURRENCY (bir vaqtda boshqarish) — bir ip, navbat bilan
biri kutganda boshqasiga o'tadi (async — I/O)
"bir oshpaz ko'p taomni navbat bilan"
PARALLELISM (bir vaqtda bajarish) — ko'p yadro, haqiqiy parallel
ko'p ish AYNI vaqtda (multiprocessing — CPU)
"ko'p oshpaz — har biri bir taom"Concurrency vs parallelism — ikki xil "bir vaqtda": Concurrency (bir vaqtda boshqarish) — bir ip ko'p vazifani navbat bilan (biri kutganda boshqasiga — async, I/O); "bir oshpaz ko'p taomni navbat bilan" (biri pishayotganda boshqasini tayyorlaydi). Parallelism (bir vaqtda bajarish) — ko'p yadro, ayni vaqtda haqiqiy parallel (multiprocessing — CPU); "ko'p oshpaz — har biri bir taom". Farq: concurrency — navbat (bir resurs, samarali kutish — I/O uchun), parallelism — haqiqiy parallel (ko'p resurs, hisoblash — CPU uchun). Async — concurrency (parallelism emas). Concurrency — boshqarish, parallelism — bajarish. Bir ip vs ko'p yadro.
2.3. Event loop (hodisalar sikli)
Async yuragi:
# event loop — vazifalarni navbat bilan boshqaradi
# vazifa I/O kutsa (await) → loop boshqasiga o'tadi
# I/O tayyor bo'lsa → vazifaga qaytadi
import asyncio
async def vazifa():
await tashqi_api() # kutish — loop boshqasiga o'tadi
asyncio.run(main()) Event loop (hodisalar sikli) — asyncio'ning yuragi: vazifalarni (coroutine) navbat bilan boshqaradi — vazifa await ga yetganda (I/O kutish) loop uni to'xtatib, boshqa tayyor vazifaga o'tadi; I/O tayyor bo'lganda vazifaga qaytadi. Sabab: kutish (await) — loop uchun "boshqa ish qil" signali (kutmasdan — 14-qism); loop bir ipda ko'p vazifani aylantiradi (biri kutganda boshqasi). asyncio.run() — loopni ishga tushiradi. Event loop — vazifa rejalashtirgichi (kutishni boshqarish). Loop — navbat bilan boshqarish. Kutsa — boshqa vazifaga.
2.4. I/O-bog'liq vs CPU-bog'liq
Async qayerda foydali:
I/O-BOG'LIQ (I/O-bound) — kutish ko'p (baza, API, fayl)
async FOYDALI (kutish paytida boshqa ish)
CPU-BOG'LIQ (CPU-bound) — hisoblash ko'p (matematik, tahlil)
async FOYDASIZ (kutish yo'q — CPU band)
yechim: multiprocessing (parallel — ko'p yadro) I/O-bog'liq vs CPU-bog'liq — ish turi async foydasini belgilaydi: I/O-bog'liq (I/O-bound — vaqtning ko'pi kutishda: baza, API, fayl, tarmoq) — async foydali (kutish paytida boshqa ish); CPU-bog'liq (CPU-bound — vaqtning ko'pi hisoblashda: matematik, ma'lumot tahlili, rasm) — async foydasiz (kutish yo'q — CPU doim band, await yo'q). CPU-bog'liq uchun: multiprocessing (14-qism — ko'p yadro, haqiqiy parallel — GIL chetlab). Sabab: async kutishni samarali qiladi (I/O), lekin hisoblashni tezlatmaydi (CPU). Ish turini bilish muhim. I/O — async, CPU — multiprocessing. To'g'ri vosita — ish turiga.
2.5. Async naqshlar (gather, semaphore)
import asyncio
# gather — ko'p vazifani parallel kutish
natijalar = await asyncio.gather(vazifa1(), vazifa2(), vazifa3())
# semaphore — bir vaqtdagi vazifalarni cheklash (10 ta)
sem = asyncio.Semaphore(10)
async def cheklangan():
async with sem: # ko'pi 10 ta bir vaqtda
await ish() Async naqshlar: gather (ko'p vazifani parallel kutish — hammasi birga, 14-qism — asyncio.gather(t1, t2, t3); ketma-ket emas — tez); Semaphore (bir vaqtdagi vazifalarni cheklash — masalan ko'pi 10 ta parallel; tashqi xizmatni bosmaslik, resurs cheklovi); as_completed (tayyor bo'lgani bilan — birinchi tugagandan); timeout (kutish chegarasi — 27.12); TaskGroup (14-qism — vazifa guruhi). Sabab: async naqshlar concurrencyni boshqaradi (parallel kutish, cheklash, timeout). gather — eng ko'p ishlatiladi (parallel I/O). Naqshlar — async ishni tashkil qilish. gather — parallel, semaphore — cheklash.
2.6. Async cheklovlari va tuzoqlar
Async cheklovlari va tuzoqlari: bloklaydigan kod (async ichida sinxron I/O yoki og'ir hisoblash — butun loopni bloklaydi! — await bilan yoki run_in_executor); CPU-bog'liq ishga async (foydasiz — multiprocessing); hamma narsani async qilish (oddiy sinxron kodga async — murakkablik, foydasiz — 14-qism); xato boshqarish (bir vazifa xato — gatherda boshqalarga ta'sir — return_exceptions); cheksiz concurrency (10,000 parallel — resurs tugaydi — semaphore bilan cheklash); async/sync aralashtirish (async funksiyani sync chaqirish — xato). Yaxshi async: I/O-bog'liq, bloklamaydigan, cheklangan (semaphore). Tuzoq — bloklash, CPU, cheksizlik. Async — kuchli, lekin ehtiyot. To'g'ri async — bloklamas, I/O.
2.7. Async va boshqa miqyoslash
Async boshqa miqyoslash usullari bilan birga: async (bir ip — ko'p I/O ulanish — samarali kutish), ko'p ip/jarayon (CPU — multiprocessing), gorizontal (ko'p server — 29.6 yuk taqsimlash), navbat (29.4 — uzoq vazifa fonga). Ular turli darajada: async — bir server ichida I/O concurrency, gorizontal — ko'p server, navbat — fon vazifa. Zamonaviy tizim ularni birlashtiradi: async veb server (FastAPI — 20-qism, ko'p ulanish) + ko'p server (yuk taqsimlash — 29.6) + navbat (uzoq vazifa — 29.4). Async I/O-bog'liq veb yuklar uchun asosi (kam resurs, ko'p ulanish). Async — bir server samaradorligi. Miqyoslash — ko'p usul birga.
2.8. Async — resursni samarali ishlatish
Async asosiy g'oyasi — resursni samarali ishlatish: I/O kutish paytida resurs (ip) bo'sh turmasdan boshqa ishga (bir ip — ko'p ulanish). Bu I/O-bog'liq yuklar (veb server, API — ko'p kutish) uchun keskin samaradorlik (an'anaviy "har ulanishga bir ip" o'rniga bir ip minglab). Async concurrency (14-qism), FastAPI (20-qism), yuk taqsimlash 29.6-bob bilan miqyoslanadigan tizimlarning asosi. Lekin faqat I/O-bog'liq uchun (CPU — multiprocessing), va murakkablik bilan (bloklash, async/sync). "To'g'ri yuk turiga to'g'ri vosita" (async I/O, multiprocessing CPU — 29.5 broker kabi). Async — kutishni ishga aylantirish. Samarali kutish — ko'p ulanish.
3. Tez ma'lumotnoma
import asyncio
# COROUTINE (async funksiya):
async def vazifa(x):
await asyncio.sleep(0) # I/O (kutish — loop boshqasiga)
return x * 2
# EVENT LOOP:
asyncio.run(main()) # loopni ishga tushiradi
# GATHER (parallel kutish):
natijalar = await asyncio.gather(vazifa(1), vazifa(2), vazifa(3))
# SEMAPHORE (concurrency cheklash):
sem = asyncio.Semaphore(10)
async def cheklangan():
async with sem: await ish()
# TIMEOUT:
await asyncio.wait_for(vazifa(), timeout=5.0)
# CONCURRENCY vs PARALLELISM:
# concurrency — bir ip, navbat (async — I/O)
# parallelism — ko'p yadro, haqiqiy parallel (multiprocessing — CPU)
# I/O-BOG'LIQ → async · CPU-BOG'LIQ → multiprocessing
# TUZOQ: bloklaydigan kod (butun loopni to'xtatadi)Katta hajmdagi async xulosasi
Async — bir ip ko'p I/O ulanish (kutish samarali)
Concurrency (navbat, bir ip) vs parallelism (ko'p yadro)
Event loop (await — kutsa boshqa vazifaga) · coroutine
I/O-bog'liq → async · CPU-bog'liq → multiprocessing
Naqshlar: gather (parallel), semaphore (cheklash) · bloklamang4. Batafsil misollar
Async 14-qismda o'rganilgan; misollar concurrency mantiqini (deterministik) modellashtiradi.
Misol 1 — Sinxron vs async (kutish vaqti)
"""Concurrency: sinxron ketma-ket vs async parallel kutish (vaqt modeli)."""
def sinxron_vaqt(sorovlar: list) -> int:
# har so'rov ketma-ket kutiladi (yig'indi)
return sum(sorovlar)
def async_vaqt(sorovlar: list) -> int:
# parallel kutish (eng uzuni — birga kutadi)
return max(sorovlar) if sorovlar else 0
def main() -> None:
# har so'rov kutish vaqti (ms)
sorovlar = [200, 200, 200, 200, 200]
print("=== 1. So'rovlar (har biri I/O kutadi) ===")
print(f" {len(sorovlar)} so'rov, har biri {sorovlar[0]}ms kutadi")
print("\n=== 2. Sinxron (ketma-ket) ===")
sinx = sinxron_vaqt(sorovlar)
print(f" jami vaqt: {sinx}ms (har so'rov navbat bilan)")
print("\n=== 3. Async (parallel kutish) ===")
asinx = async_vaqt(sorovlar)
print(f" jami vaqt: {asinx}ms (birga kutadi)")
print("\n=== 4. Tezlashish ===")
print(f" sinxron: {sinx}ms, async: {asinx}ms")
print(f" ~{sinx // asinx}x tez (parallel I/O)")
print(" kutish paytida boshqa so'rov (bir ip)")
print(" ⭐ Async — parallel kutish (I/O)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. So'rovlar (har biri I/O kutadi) ===
5 so'rov, har biri 200ms kutadi
=== 2. Sinxron (ketma-ket) ===
jami vaqt: 1000ms (har so'rov navbat bilan)
=== 3. Async (parallel kutish) ===
jami vaqt: 200ms (birga kutadi)
=== 4. Tezlashish ===
sinxron: 1000ms, async: 200ms
~5x tez (parallel I/O)
kutish paytida boshqa so'rov (bir ip)
⭐ Async — parallel kutish (I/O)Nima ko'rsatdi: 2.1, 2.5-bo'limlar.
Misol 2 — Event loop (navbat bilan boshqarish)
"""Event loop: vazifalar await'ga yetganda boshqasiga o'tadi (navbat)."""
class EventLoop:
def __init__(self) -> None:
self.jurnal: list = []
def ishga_tushir(self, vazifalar: list) -> None:
# har vazifa qadamlardan iborat (await — to'xtash nuqtasi)
navbat = [(nom, qadamlar) for nom, qadamlar in vazifalar]
while navbat:
nom, qadamlar = navbat.pop(0)
if qadamlar:
qadam = qadamlar.pop(0)
self.jurnal.append(f"{nom}: {qadam}")
if qadamlar:
# await — boshqa vazifaga o'tadi (oxirga)
navbat.append((nom, qadamlar))
def main() -> None:
loop = EventLoop()
# ikki vazifa, har biri 2 qadam (await orasida)
vazifalar = [
("vazifa-A", ["so'rov yubor", "javob qayta ishla"]),
("vazifa-B", ["so'rov yubor", "javob qayta ishla"]),
]
print("=== 1. Ikki vazifa (har biri await bilan) ===")
loop.ishga_tushir(vazifalar)
print("\n=== 2. Bajarilish tartibi ===")
for satr in loop.jurnal:
print(f" {satr}")
print("\n=== 3. Aralashib bajarildi (navbat) ===")
print(" A so'rov → B so'rov → A javob → B javob")
print(" A kutganda (await) B ishladi (bir ip)")
print("\n=== 4. Event loop ===")
print(" await — boshqa vazifaga o'tish nuqtasi")
print(" bir ip ko'p vazifani boshqaradi (concurrency)")
print(" ⭐ Event loop — navbat bilan boshqarish")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Ikki vazifa (har biri await bilan) ===
=== 2. Bajarilish tartibi ===
vazifa-A: so'rov yubor
vazifa-B: so'rov yubor
vazifa-A: javob qayta ishla
vazifa-B: javob qayta ishla
=== 3. Aralashib bajarildi (navbat) ===
A so'rov → B so'rov → A javob → B javob
A kutganda (await) B ishladi (bir ip)
=== 4. Event loop ===
await — boshqa vazifaga o'tish nuqtasi
bir ip ko'p vazifani boshqaradi (concurrency)
⭐ Event loop — navbat bilan boshqarishNima ko'rsatdi: 2.2, 2.3-bo'limlar.
Misol 3 — I/O-bog'liq vs CPU-bog'liq
"""Ish turi: I/O-bog'liq (async foydali) vs CPU-bog'liq (multiprocessing)."""
def ish_tahlil(kutish_ms: int, hisoblash_ms: int) -> dict:
jami = kutish_ms + hisoblash_ms
kutish_foiz = round(kutish_ms / jami * 100) if jami else 0
tur = "I/O-bog'liq" if kutish_foiz > 50 else "CPU-bog'liq"
tavsiya = "async" if tur == "I/O-bog'liq" else "multiprocessing"
return {"tur": tur, "kutish_foiz": kutish_foiz, "tavsiya": tavsiya}
def main() -> None:
print("=== 1. Veb API (ko'p kutish) ===")
r = ish_tahlil(kutish_ms=180, hisoblash_ms=20)
print(f" kutish: {r['kutish_foiz']}% → {r['tur']}")
print(f" tavsiya: {r['tavsiya']}")
print("\n=== 2. Ma'lumot tahlili (ko'p hisoblash) ===")
r = ish_tahlil(kutish_ms=10, hisoblash_ms=190)
print(f" kutish: {r['kutish_foiz']}% → {r['tur']}")
print(f" tavsiya: {r['tavsiya']}")
print("\n=== 3. Nega farq ===")
print(" I/O-bog'liq: kutish ko'p → async (kutish paytida boshqa)")
print(" CPU-bog'liq: hisoblash ko'p → async foydasiz (CPU band)")
print("\n=== 4. To'g'ri vosita ===")
print(" async — I/O (kutish), multiprocessing — CPU (hisoblash)")
print(" ish turini bilish muhim")
print(" ⭐ I/O → async, CPU → multiprocessing")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Veb API (ko'p kutish) ===
kutish: 90% → I/O-bog'liq
tavsiya: async
=== 2. Ma'lumot tahlili (ko'p hisoblash) ===
kutish: 5% → CPU-bog'liq
tavsiya: multiprocessing
=== 3. Nega farq ===
I/O-bog'liq: kutish ko'p → async (kutish paytida boshqa)
CPU-bog'liq: hisoblash ko'p → async foydasiz (CPU band)
=== 4. To'g'ri vosita ===
async — I/O (kutish), multiprocessing — CPU (hisoblash)
ish turini bilish muhim
⭐ I/O → async, CPU → multiprocessingNima ko'rsatdi: 2.4-bo'lim.
Misol 4 — Semaphore (concurrency cheklash)
"""Semaphore: bir vaqtdagi vazifalarni cheklash (resurs/tashqi xizmat)."""
class Semaphore:
def __init__(self, chegara: int) -> None:
self.chegara = chegara
self.faol = 0
self.kutayotgan: list = []
def bajar(self, vazifalar: list) -> list:
jurnal = []
navbat = list(vazifalar)
while navbat or self.faol > 0:
# chegaragacha vazifalarni boshlash
while navbat and self.faol < self.chegara:
v = navbat.pop(0)
self.faol += 1
jurnal.append(f"{v} boshlandi (faol: {self.faol})")
# bittasi tugadi (faol kamayadi)
if self.faol > 0:
self.faol -= 1
jurnal.append(f"vazifa tugadi (faol: {self.faol})")
return jurnal
def main() -> None:
sem = Semaphore(chegara=2) # ko'pi 2 parallel
print("=== 1. 5 vazifa, chegara 2 ===")
jurnal = sem.bajar(["v1", "v2", "v3", "v4", "v5"])
print("\n=== 2. Bajarilish (ko'pi 2 parallel) ===")
for satr in jurnal[:8]:
print(f" {satr}")
print("\n=== 3. Nega cheklash ===")
print(" cheksiz parallel — resurs tugaydi (10000 ulanish)")
print(" tashqi xizmatni bosmaslik (rate limit)")
print("\n=== 4. Semaphore ===")
print(" bir vaqtda ko'pi N vazifa (cheklangan)")
print(" qolganlar kutadi (navbat)")
print(" ⭐ Semaphore — concurrency cheklash")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. 5 vazifa, chegara 2 ===
=== 2. Bajarilish (ko'pi 2 parallel) ===
v1 boshlandi (faol: 1)
v2 boshlandi (faol: 2)
vazifa tugadi (faol: 1)
v3 boshlandi (faol: 2)
vazifa tugadi (faol: 1)
v4 boshlandi (faol: 2)
vazifa tugadi (faol: 1)
v5 boshlandi (faol: 2)
=== 3. Nega cheklash ===
cheksiz parallel — resurs tugaydi (10000 ulanish)
tashqi xizmatni bosmaslik (rate limit)
=== 4. Semaphore ===
bir vaqtda ko'pi N vazifa (cheklangan)
qolganlar kutadi (navbat)
⭐ Semaphore — concurrency cheklashNima ko'rsatdi: 2.5, 2.6-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Har ulanishga bir ip" | Async (bir ip ko'p ulanish) |
| "Async = parallel" | Concurrency (navbat, bir ip) |
| "Async hamma ishga" | I/O-bog'liq (CPU — multiprocessing) |
| "Async CPU ni tezlatadi" | Foydasiz (kutish yo'q) |
| "await bloklaydi" | Boshqa vazifaga o'tadi |
| "Cheksiz parallel" | Semaphore (cheklash) |
| "Bloklaydigan kod mayli" | Butun loopni to'xtatadi |
| "Async — sehr" | Kutishni samarali (I/O) |
6. Keng tarqalgan xatolar va yechimlari
1. Bloklaydigan kod async ichida
async def f(): time.sleep(5) # butun loop bloklandi # ⚠️
async def f(): await asyncio.sleep(5) # ✅2. CPU-bog'liq ishga async
async def hisobla(): ogir_matematika() # CPU band # ⚠️
# multiprocessing (parallel — ko'p yadro) # ✅3. Ketma-ket await (parallel emas)
a = await t1(); b = await t2() # ketma-ket # ⚠️
a, b = await asyncio.gather(t1(), t2()) # parallel # ✅4. Cheksiz concurrency
await asyncio.gather(*[f() for _ in range(100000)]) # ⚠️
# semaphore (cheklash — resurs) # ✅5. Async funksiyani await'siz chaqirish
vazifa() # coroutine yaratildi, bajarilmadi # ⚠️
await vazifa() # yoki asyncio.create_task # ✅6. gather'da xato boshqarilmagan
await gather(t1, t2) # bir xato — hammasi to'xtaydi # ⚠️
gather(t1, t2, return_exceptions=True) # ✅7. Hamma narsani async qilish
async def qosh(a, b): return a + b # oddiy (foydasiz) # ⚠️
def qosh(a, b): return a + b # sinxron (oddiy ish) # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 14-qism (o'tilgan): Async asoslari (asyncio, coroutine)
- 20-qism (o'tilgan): FastAPI — async veb server
- 29.6-dars (o'tilgan): Yuk taqsimlash — ko'p server
- 29.4-dars (o'tilgan): Navbat — CPU/uzoq vazifa
- 26.3-dars (o'tilgan): HTTP so'rovlar — async
8. Eng yaxshi amaliyotlar
Async — I/O-bog'liq (CPU — multiprocessing).
Bloklamang (async I/O — time.sleep emas).
gather (parallel kutish — ketma-ket emas).
Semaphore (concurrency cheklash — resurs).
Timeout (kutish chegarasi — 27.12).
Xato boshqar (gather return_exceptions).
Oddiy ish — sinxron (async majburlama emas).
Async + gorizontal + navbat (birga).
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # nega async (I/O-bog'liq)?
2. # concurrency nima?
3. # parallelism nima?
4. # concurrency vs parallelism?
5. # event loop nima?
6. # await nima qiladi?
7. # I/O-bog'liq nima?
8. # CPU-bog'liq nima?
9. # CPU-bog'liq uchun nima?
10. # gather nima?
11. # semaphore nima?
12. # bloklaydigan kod?Javoblar
- I/O kutish paytida boshqa ish (samarali)
- Bir vaqtda boshqarish (bir ip, navbat)
- Bir vaqtda bajarish (ko'p yadro)
- Concurrency navbat, parallelism haqiqiy parallel
- Vazifalarni navbat bilan boshqaruvchi
- Boshqa vazifaga o'tadi (kutish)
- Kutish ko'p (baza, API, fayl)
- Hisoblash ko'p (matematik)
- Multiprocessing (parallel — ko'p yadro)
- Ko'p vazifani parallel kutish
- Concurrencyni cheklash (ko'pi N)
- Butun loopni to'xtatadi (async I/O emas)
Vazifa 2: Xatolarni tuzating
1. async def f(): time.sleep(5)
2. async def h(): ogir_matematika()
3. a = await t1(); b = await t2()
4. gather(*[f() for _ in range(100000)])
5. vazifa() # await'sizJavoblar
1. await asyncio.sleep(5)
2. multiprocessing (CPU)
3. await asyncio.gather(t1(), t2())
4. semaphore (cheklash)
5. await vazifa()Vazifa 3: Sinxron vs async
Modellang:
- So'rovlar
- Sinxron (ketma-ket)
- Async (parallel)
- Tezlashish
Vazifa 4: Event loop
Modellang:
- Vazifalar
- await
- Navbat
- Aralash
Vazifa 5: Ish turi
Modellang:
- Kutish/hisoblash
- I/O-bog'liq
- CPU-bog'liq
- Tavsiya
Vazifa 6: Semaphore
Modellang:
- Chegara
- Faol
- Cheklash
- Navbat
Vazifa 7: O'ylash
Async "concurrency" (bir vaqtda boshqarish) beradi, lekin "parallelism" (bir vaqtda bajarish) emas — bu farq ko'plarni chalkashtiradi. Nima uchun "bir ip ko'p ulanishni boshqarishi" (parallel bajarmasdan) I/O-bog'liq yuklar uchun etarli va samarali, va nega "to'g'ri vosita to'g'ri ish uchun" (async I/O ga, multiprocessing CPU ga) muhandislikda takrorlanadigan tamoyil?
Javob
Qisqa javob: "Bir ip ko'p ulanishni boshqarishi" I/O-bog'liq yuklar uchun etarli, chunki: I/O-bog'liq ishda vaqtning ko'pi kutishda o'tadi (baza javobi, tarmoq — CPU ish qilmaydi, faqat kutadi) — bu kutish paytida ip bo'sh (behuda). Concurrency bu bo'sh vaqtni ishga soladi: bir ulanish kutganda (I/O), ip boshqa ulanishga o'tadi (yana kutishga qo'yadi), keyin uchinchiga... — bir ip minglab ulanishni "aylantiradi" (har biri kutganda navbat beradi). Parallelism (haqiqiy bir vaqtda bajarish) kerak emas, chunki hech qaysi ulanish CPU'ni band qilmaydi (ular kutadi) — parallel bajarish uchun hech narsa yo'q (kutishni parallel qilishdan foyda yo'q — ular baribir kutadi). Analogiya: bir oshpaz (ip) ko'p taomni (ulanish) pishiradi — biri o'choqda pishayotganda (kutish) boshqasini tayyorlaydi (CPU ish) — oshpaz doim band, hech taom kutmaydi; ikkinchi oshpaz (parallel) kerak emas (biror taomni tezroq pishirmaydi — pishish vaqti bir xil). CPU-bog'liq boshqacha: taom doimiy aralashtirishni talab qilsa (CPU) — bir oshpaz navbat bilan ulgurmaydi (biri aralashtirsa, boshqasi kutadi — sekin) — ko'p oshpaz (parallel — multiprocessing) kerak. "To'g'ri vosita to'g'ri ish uchun" takrorlanadi, chunki: har vosita muayyan ish turiga optimallashtirilgan (async — kutish/I/O, multiprocessing — hisoblash/CPU) — noto'g'ri joyda foydasiz yoki zararli (async CPU'ni tezlatmaydi — kutish yo'q; multiprocessing I/O'ga ortiqcha — jarayon qimmat). Bu 29.5 (broker — RabbitMQ/Kafka), 27.9 (monolit/mikroservis), 28.13 (cloud) da ham: kontekstga qarab tanlov, universal yechim yo'q. Muhandislik saboqlari: concurrency (boshqarish) I/O uchun yetadi (kutishni ishga solish); parallelism (bajarish) CPU uchun (hisoblash); to'g'ri vosita ish turiga (async I/O, multiprocessing CPU); universal yechim yo'q (ishni tushun, vositani tanla).
1. Nega concurrency I/O uchun yetadi
I/O — kutish ko'p (CPU bo'sh). Concurrency bo'sh vaqtni ishga soladi (kutganda boshqa ulanishga). Bir ip minglab (kutishni aylantiradi).
2. Nega parallelism kerak emas (I/O)
Ulanishlar kutadi (CPU band emas). Parallel bajarish uchun hech narsa yo'q (kutishni parallel qilishdan foyda yo'q).
3. Oshpaz analogiyasi
I/O: bir oshpaz ko'p taom (biri pishayotganda boshqasi tayyorlanadi — doim band). CPU: doimiy aralashtirish — ko'p oshpaz kerak (parallel).
4. Nega to'g'ri vosita
| Ish | Vosita |
|---|---|
| I/O-bog'liq (kutish) | async (concurrency) |
| CPU-bog'liq (hisoblash) | multiprocessing (parallel) |
Noto'g'ri joyda foydasiz (async CPU'ni tezlatmaydi).
5. Muhandislik saboqlari
- Concurrency I/O uchun yetadi (kutishni ishga solish)
- Parallelism CPU uchun (hisoblash)
- To'g'ri vosita ish turiga
- Universal yechim yo'q
6. Xulosa
- I/O — kutish ko'p → concurrency (bir ip minglab)
- Parallelism kerak emas (ular kutadi)
- CPU — parallel kerak (multiprocessing)
- To'g'ri vosita ish turiga
Nimani mustahkamlaydi: 2.2, 2.4-bo'limlar.
Xulosa
Bu darsda katta hajmdagi async ni o'rgandik.
Eng muhim uch fikr:
Nega async va concurrency vs parallelism. Ko'p ish I/O-bog'liq (baza, API, fayl — kutish) — kutish paytida resurs bo'sh turadi; async kutish paytida boshqa ishga o'tadi (bir ip — ko'p ulanish, kam resurs). Concurrency (bir vaqtda boshqarish) — bir ip ko'p vazifani navbat bilan (biri kutganda boshqasiga — async, I/O; "bir oshpaz ko'p taom"); Parallelism (bir vaqtda bajarish) — ko'p yadro, ayni vaqtda haqiqiy parallel (multiprocessing — CPU; "ko'p oshpaz"). Async — concurrency (parallelism emas).
Event loop va ish turi. Event loop — asyncio yuragi: vazifa
awaitga yetganda (I/O) loop uni to'xtatib boshqa tayyor vazifaga o'tadi (I/O tayyor bo'lganda qaytadi) — bir ipda ko'p vazifa. I/O-bog'liq vs CPU-bog'liq: I/O-bog'liq (vaqt ko'pi kutishda — baza, API) — async foydali; CPU-bog'liq (vaqt ko'pi hisoblashda — matematik) — async foydasiz (kutish yo'q, CPU band), yechim multiprocessing (ko'p yadro, GIL chetlab). Ish turini bilish muhim (async I/O, multiprocessing CPU).Naqshlar, tuzoqlar, samaradorlik. Naqshlar:
gather(ko'p vazifani parallel kutish — tez, ketma-ket emas),Semaphore(concurrency cheklash — ko'pi N parallel, resurs/rate limit),timeout. Tuzoqlar: bloklaydigan kod (async ichida sinxron I/O/og'ir hisoblash — butun loopni bloklaydi!), CPU-bog'liq ishga async (foydasiz), cheksiz concurrency (semaphore), hamma narsani async. Async — resursni samarali ishlatish (kutishni ishga aylantirish — bir ip minglab ulanish), I/O-bog'liq veb yuklar (FastAPI 20-qism) uchun asosi; boshqa miqyoslash (gorizontal 29.6, navbat 29.4) bilan birga. "Bir ip ko'p ulanish" I/O uchun yetadi (kutish — parallelism kerak emas); "to'g'ri vosita to'g'ri ish uchun" (async I/O, multiprocessing CPU — universal tamoyil).
Keyingi darsda xotira optimizatsiyasini o'rganamiz: xotira sarfini kamaytirish — xotira oqishi (memory leak), generatorlar, __slots__, ma'lumot tuzilmalarini samarali tanlash va katta ma'lumot bilan xotira-samarali ishlash.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!