Bosh sahifa Wiki Coroutine

Coroutine

Coroutine — bajarilishini ma’lum nuqtada to‘xtatib, holatini saqlagan holda keyin davom ettira oladigan dasturiy bajarilish birligi.

Oddiy funksiya chaqiriladi, natija qaytaradi va tugaydi. Coroutine esa yield, await yoki runtime mexanizmi orqali boshqaruvni vaqtincha qaytarib, keyinchalik ayni joydan davom etadi.

Coroutine asynchronous I/O, event loop, generator va cooperative multitaskingda qo‘llanadi.

Asosiy xususiyat

Coroutine to‘xtaganda quyidagi holat saqlanadi:

  • instruction position;
  • local variable;
  • exception context;
  • kutayotgan operation;
  • runtime metadata.

Qayta ishga tushirilganda funksiya boshidan emas, to‘xtagan nuqtadan davom etadi.

Stackful va stackless

Stackful coroutine

Har coroutine o‘z stackiga ega. Oddiy function calllar ichidan ham yield qilish mumkin.

Afzalligi — tabiiy control flow. Kamchiligi — stack xotirasi va context switching murakkabligi.

Stackless coroutine

Compiler yoki runtime holat mashinasiga aylantiradi.

async/await ko‘p tillarda stackless modelga yaqin.

Xotira sarfi kichik, lekin faqat belgilangan await nuqtalarida to‘xtaydi.

Generator

Generator coroutine’ning sodda ko‘rinishi.

Misol mantiqi:

yield 1
yield 2
yield 3

Har chaqirishda keyingi qiymat qaytadi.

Generator katta ma’lumotni bir yo‘la xotiraga yuklamasdan bosqichma-bosqich ishlab chiqishi mumkin.

Async va await

async funksiya coroutine yaratadi. await uzoq operatsiya tugashini kutib, event loopga boshqa vazifalarni bajarish imkonini beradi.

Masalan:

  1. HTTP so‘rov yuboriladi.
  2. Coroutine socket javobini kutishda to‘xtaydi.
  3. Event loop boshqa coroutinelarni ishlatadi.
  4. Javob kelganda oldingi coroutine davom etadi.

Bu kutish vaqtida threadni band qilmaslikka yordam beradi.

Cooperative scheduling

Coroutine o‘zi boshqaruvni qaytarmaguncha ishlaydi.

Bu cooperative scheduling hisoblanadi.

Afzalligi:

Kamchiligi — coroutine uzoq CPU ishida yield qilmasa, event loop bloklanadi.

Event loop

Event loop:

  • tayyor coroutine;
  • timer;
  • socket event;
  • callback;
  • future

ni boshqaradi.

U I/O tayyorligi haqida operatsion tizimdan epoll, kqueue yoki boshqa mexanizm orqali xabar oladi.

Future va Promise

Future keyinchalik tayyor bo‘ladigan natijani ifodalaydi.

Coroutine future’ni await qiladi.

Natija:

  • muvaffaqiyatli qiymat;
  • exception;
  • cancellation

bo‘lishi mumkin.

Promise ayrim tillarda natijani ishlab chiqaruvchi tomonni bildiradi.

Task

Runtime coroutine’ni schedule qilingan Taskga o‘raydi.

Task:

  • holat;
  • natija;
  • exception;
  • cancellation;
  • callback

ni boshqaradi.

Coroutine obyektini yaratish uning avtomatik ishga tushganini har doim anglatmaydi.

Coroutine va thread

Jihat Coroutine Thread
Scheduling Odatda runtime Kernel
Switch Cooperative Preemptive bo‘lishi mumkin
Xotira Kichikroq Stack kattaroq
Parallel CPU O‘zi bilan emas Ko‘p coreda mumkin
I/O concurrency Juda qulay Mumkin
Blocking call Event loopni bloklaydi Bitta threadni bloklaydi

Coroutine threadlar ustida ishlaydi. Ular bir-birini inkor qilmaydi.

Blocking kod

Async funksiya ichida oddiy blocking disk yoki network chaqirig‘i ishlatilsa, event loop to‘xtaydi.

Yechimlar:

CPU-bound vazifa

Katta hisob coroutine uchun mos emas, chunki event loop boshqa vazifalarni bajara olmaydi.

CPU-bound ish:

ga beriladi.

Cancellation

Task bekor qilinganda coroutinega cancellation signali yoki exception beriladi.

Coroutine:

ni finally yoki cleanup blokida yopishi kerak.

Cancellationni butunlay yutib yuborish shutdownni qiyinlashtiradi.

Timeout

Timeout coroutine’ni belgilangan muddatdan keyin bekor qiladi.

Timeout qo‘llanganda background operation haqiqatan to‘xtaganmi yoki faqat natijani kutish tugaganmi aniqlanadi.

Database yoki remote serverda amal davom etishi mumkin.

Structured concurrency

Child tasklar parent scope bilan boshqariladi.

Scope tugaganda barcha child task:

  • tugagan;
  • bekor qilingan;
  • exceptioni qayta ishlangan

bo‘lishi kerak.

Bu orphan task va yashirin exceptionlarni kamaytiradi.

Race condition

Coroutine cooperative bo‘lsa ham race condition yuz berishi mumkin.

Coroutine umumiy state’ni o‘zgartirish orasida await qilsa, boshqa coroutine shu state’ga kiradi.

Async mutex, queue yoki immutable data ishlatiladi.

Backpressure

Producer coroutinesi consumerdan tez ishlasa, queue cheksiz o‘sishi mumkin.

Bounded queue producer’ni vaqtincha kutdiradi.

Bu backpressure xotira sarfini boshqaradi.

Debugging

Async stack oddiy call stackdan murakkabroq.

Vositalar:

Coroutine yaratilgan, ammo await qilinmagan bo‘lsa warning chiqishi mumkin.

Coroutine lifecycle

Coroutine quyidagi holatlarda bo‘lishi mumkin:

  • yaratilgan;
  • schedule qilingan;
  • ishlayotgan;
  • await holatida;
  • tugagan;
  • bekor qilingan;
  • xato bilan tugagan.

Tugagan coroutine qayta boshlanmaydi. Yangi ish uchun yangi coroutine obyekt yaratiladi.

Context propagation

Tracing ID, user context va deadline asynchronous chaqiriqlar bo‘ylab uzatilishi kerak. Oddiy thread-local qiymat event loopda bir nechta request orasida aralashishi mumkin.

Async runtime context variable yoki task-local storage beradi. Worker threadga o‘tilganda contextni alohida ko‘chirish talab qilinishi mumkin.

Resource cleanup

Coroutine suspended holatda file yoki connectionni ushlab turishi mumkin. Scope tugaganda asynchronous context manager yoki finally bloki resursni bo‘shatadi. Aks holda connection pool asta-sekin tugaydi.

Bog‘liq tushunchalar

Async, Await, Event loop, Generator, Future, Task, Thread, Cooperative multitasking, Cancellation, Backpressure