IlmHamroh
Python kursi/Miqyos va unumdorlik8/10-dars20 daqiqa
Mundarija (22)

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 = 200ms

Nega 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:

python
# 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)

python
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

python
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) · bloklamang

4. Batafsil misollar

Async 14-qismda o'rganilgan; misollar concurrency mantiqini (deterministik) modellashtiradi.

Misol 1 — Sinxron vs async (kutish vaqti)

python
"""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:

text
=== 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)

python
"""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:

text
=== 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 boshqarish

Nima ko'rsatdi: 2.2, 2.3-bo'limlar.

Misol 3 — I/O-bog'liq vs CPU-bog'liq

python
"""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:

text
=== 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 → multiprocessing

Nima ko'rsatdi: 2.4-bo'lim.

Misol 4 — Semaphore (concurrency cheklash)

python
"""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:

text
=== 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 cheklash

Nima 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

python
async def f(): time.sleep(5)   # butun loop bloklandi  # ⚠️
async def f(): await asyncio.sleep(5)                  # ✅

2. CPU-bog'liq ishga async

python
async def hisobla(): ogir_matematika()   # CPU band   # ⚠️
# multiprocessing (parallel — ko'p yadro)               # ✅

3. Ketma-ket await (parallel emas)

python
a = await t1(); b = await t2()   # ketma-ket           # ⚠️
a, b = await asyncio.gather(t1(), t2())   # parallel    # ✅

4. Cheksiz concurrency

python
await asyncio.gather(*[f() for _ in range(100000)])    # ⚠️
# semaphore (cheklash — resurs)                          # ✅

5. Async funksiyani await'siz chaqirish

python
vazifa()   # coroutine yaratildi, bajarilmadi          # ⚠️
await vazifa()   # yoki asyncio.create_task            # ✅

6. gather'da xato boshqarilmagan

python
await gather(t1, t2)   # bir xato — hammasi to'xtaydi   # ⚠️
gather(t1, t2, return_exceptions=True)                  # ✅

7. Hamma narsani async qilish

python
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

  1. Async — I/O-bog'liq (CPU — multiprocessing).

  2. Bloklamang (async I/O — time.sleep emas).

  3. gather (parallel kutish — ketma-ket emas).

  4. Semaphore (concurrency cheklash — resurs).

  5. Timeout (kutish chegarasi — 27.12).

  6. Xato boshqar (gather return_exceptions).

  7. Oddiy ish — sinxron (async majburlama emas).

  8. Async + gorizontal + navbat (birga).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
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
  1. I/O kutish paytida boshqa ish (samarali)
  2. Bir vaqtda boshqarish (bir ip, navbat)
  3. Bir vaqtda bajarish (ko'p yadro)
  4. Concurrency navbat, parallelism haqiqiy parallel
  5. Vazifalarni navbat bilan boshqaruvchi
  6. Boshqa vazifaga o'tadi (kutish)
  7. Kutish ko'p (baza, API, fayl)
  8. Hisoblash ko'p (matematik)
  9. Multiprocessing (parallel — ko'p yadro)
  10. Ko'p vazifani parallel kutish
  11. Concurrencyni cheklash (ko'pi N)
  12. Butun loopni to'xtatadi (async I/O emas)

Vazifa 2: Xatolarni tuzating

python
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'siz
Javoblar
python
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:

  1. So'rovlar
  2. Sinxron (ketma-ket)
  3. Async (parallel)
  4. Tezlashish

Vazifa 4: Event loop

Modellang:

  1. Vazifalar
  2. await
  3. Navbat
  4. Aralash

Vazifa 5: Ish turi

Modellang:

  1. Kutish/hisoblash
  2. I/O-bog'liq
  3. CPU-bog'liq
  4. Tavsiya

Vazifa 6: Semaphore

Modellang:

  1. Chegara
  2. Faol
  3. Cheklash
  4. 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

  1. Concurrency I/O uchun yetadi (kutishni ishga solish)
  2. Parallelism CPU uchun (hisoblash)
  3. To'g'ri vosita ish turiga
  4. Universal yechim yo'q

6. Xulosa

  1. I/O — kutish ko'p → concurrency (bir ip minglab)
  2. Parallelism kerak emas (ular kutadi)
  3. CPU — parallel kerak (multiprocessing)
  4. 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:

  1. 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).

  2. Event loop va ish turi. Event loop — asyncio yuragi: vazifa await ga 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).

  3. 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.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
29.8-dars: Katta hajmdagi async — IlmHamroh