Sobes.tech
Middle+

Jaké mechanismy umožňují kooperativní multitasking v korutinách?

sobes.tech AI

Odpověď od AI

V korutinách je kooperativní multitasking realizován prostřednictvím následujících mechanismů:

  • Suspension Points: Korutina může být "pozastavena" na určitých místech (suspension points), aniž by blokovala vlákno. To se děje při volání funkcí suspend. Během pozastavení je vlákno, ve kterém se korutina vykonávala, volné pro jiné úkoly.

  • Dispatchers: Korutiny používají Dispatchers k určení poolu vláken, na kterých budou vykonávány. Korutina může být pozastavena na jednom vlákně a obnovena na jiném.

  • Continuace: Každýkrát, když je korutina pozastavena, je vytvořen objekt Continuation, který ukládá stav korutiny v daném okamžiku. Při obnovení korutiny tento objekt používá k obnovení jejího stavu a pokračování od místa, kde byla pozastavena.

  • Spolupráce: Vývojář explicitně uvádí body pozastavení (suspend) v kódu. To činí multitasking "kooperativním" – korutina dobrovolně předává kontrolu jiné korutině nebo úkolu na určitých místech, místo aby byla nuceně přerušena operačním systémem, jako v případě preemptivního multitaskingu.

  • Strukturovaná konkurence: Korutiny jsou vázány na určitý rozsah (CoroutineScope). To umožňuje zrušit skupinu korutin současně a zajišťuje, že všechny podřízené korutiny budou dokončeny při ukončení rodičovského rozsahu.

// Příklad suspendované funkce, která vytváří suspension point
suspend fun fetchDataFromNetwork(): String {
    // Simulace síťové žádosti
    delay(1000) // Je to suspendovaná funkce - suspension point
    return "Data přijata"
}

fun main() = runBlocking {
    // runBlocking vytváří CoroutineScope a blokuje aktuální vlákno do dokončení korutiny
    println("Začátek")

    launch {
        // Spouští korutinu na jiném vlákně (nebo stejném, podle dispatcheru)
        val data = fetchDataFromNetwork() // Zde může být korutina pozastavena
        println("Přijato: $data")
    }

    println("Konec (hlavní vlákno není blokováno fetchDataFromNetwork)")
    // Hlavní vlákno může vykonávat jiné úkoly, zatímco fetchDataFromNetwork čeká
}