Príklady korutín C++

Priklady Korutin C



Coroutines poskytujú jazykovú funkciu, ktorá vám umožňuje písať asynchrónny kód organizovanejším a lineárnejším spôsobom, pričom podporuje štruktúrovaný a sekvenčný prístup. Poskytujú mechanizmus na pozastavenie a opätovné spustenie vykonávania funkcie v konkrétnych prípadoch bez zastavenia celého vlákna. Korutíny sú užitočné pri spracovávaní úloh, ktoré vyžadujú čakanie na I/O operácie, ako je čítanie zo súboru alebo odosielanie sieťového hovoru.

Korutíny sú založené na koncepte generátorov, kde funkcia môže generovať hodnoty a neskôr byť obnovená, aby pokračovala vo vykonávaní. Coroutines poskytujú výkonný nástroj na správu asynchrónnych operácií a môžu výrazne zlepšiť celkovú kvalitu vášho kódu.

Použitie korutínov

Korutíny sú v modernom programovaní potrebné z niekoľkých dôvodov, najmä v jazykoch ako C++. Tu je niekoľko kľúčových dôvodov, prečo sú koroutíny prospešné:







Coroutines poskytujú elegantné riešenie asynchrónneho programovania. Umožňujú vytvoriť kód, ktorý sa javí ako sekvenčný a blokujúci, čo je jednoduchšie na uvažovanie a pochopenie. Korutíny môžu pozastaviť svoje vykonávanie v konkrétnych bodoch bez blokovania vlákien, čo umožňuje paralelnú prevádzku iných úloh. Vďaka tomu môžu byť systémové prostriedky využívané efektívnejšie a odozva je zvýšená v aplikáciách, ktoré zahŕňajú I/O operácie alebo čakanie na externé udalosti.



Môžu uľahčiť pochopenie a údržbu kódu. Odstránením zložitých reťazcov spätného volania alebo stavových automatov umožňujú korutíny písať kód lineárnejším a sekvenčným štýlom. To zlepšuje organizáciu kódu, znižuje vnorenie a uľahčuje pochopenie logiky.



Korutíny poskytujú štruktúrovaný spôsob, ako zvládnuť súbežnosť a paralelizmus. Umožňujú vám vyjadriť zložité koordinačné vzorce a asynchrónne pracovné postupy pomocou intuitívnejšej syntaxe. Na rozdiel od tradičných modelov vlákien, kde môžu byť vlákna blokované, korutíny môžu uvoľniť systémové prostriedky a umožniť efektívny multitasking.





Vytvorme niekoľko príkladov na demonštráciu implementácie korutínov v C++.

Príklad 1: Základné korutíny

Základný príklad korutínov je uvedený v nasledujúcom texte:



#include

#include

štrukturovať Toto Corout {

štrukturovať typ_sľubu {

ThisCorout get_return_object ( ) { vrátiť { } ; }

std :: pozastaviť_nikdy initial_suspend ( ) { vrátiť { } ; }

std :: pozastaviť_nikdy final_suspend ( ) nookrem { vrátiť { } ; }

neplatné unhandled_exception ( ) { }

neplatné return_void ( ) { }

} ;

bool wait_ready ( ) { vrátiť falošný ; }

neplatné wait_suspend ( std :: coroutine_handle <> h ) { }

neplatné wait_resume ( ) { std :: cout << 'Koroutín je obnovený.' << std :: endl ; }

} ;

TentoCorout foo ( ) {

std :: cout << 'Koroutín sa začal.' << std :: endl ;

co_await std :: suspend_always { } ;

co_return ;

}

int Hlavná ( ) {

auto cr = foo ( ) ;

std :: cout << 'Koroutín je vytvorený.' << std :: endl ;

cr. wait_resume ( ) ;

std :: cout << 'Koroutín skončil.' << std :: endl ;

vrátiť 0 ;

}

Poďme si prejsť predtým poskytnutý kód a podrobne ho vysvetliť:

Po zahrnutí požadovaných hlavičkových súborov definujeme štruktúru „ThisCorout“, ktorá predstavuje korutín. Vo vnútri „ThisCorout“ je definovaná ďalšia štruktúra „promise_type“, ktorá spracováva prísľub korutínu. Táto štruktúra poskytuje rôzne funkcie, ktoré vyžaduje korutínový mechanizmus.

V zátvorkách používame funkciu get_return_object(). Vracia samotný objekt coroutine. V tomto prípade vráti prázdny objekt „ThisCorout“. Potom sa vyvolá funkcia initial_suspend(), ktorá určí správanie pri prvom spustení korutíny. Std::suspend_never znamená, že korutín by nemal byť na začiatku pozastavený.

Potom máme funkciu final_suspend(), ktorá určuje správanie, keď sa koroutín skončí. std::suspend_never znamená, že korutín by nemal byť pozastavený pred jeho dokončením.

Ak koroutín vyvolá výnimku, vyvolá sa metóda unhandled_exception(). V tomto príklade je to prázdna funkcia, ale podľa potreby môžete spracovať výnimky. Keď sa rutina ukončí bez získania hodnoty, vyvolá sa metóda return_void(). V tomto prípade je to tiež prázdna funkcia.

V rámci „ThisCorout“ definujeme aj tri členské funkcie. Funkcia wait_ready() sa volá, aby skontrolovala, či je korutín pripravený pokračovať vo vykonávaní. V tomto príklade vždy vráti hodnotu false, čo znamená, že korutín nie je pripravený na okamžité obnovenie. Keď sa má koroutín pozastaviť, zavolá sa metóda wait_suspend(). Tu je to prázdna funkcia, čo znamená, že nie je potrebné žiadne pozastavenie. Program zavolá wait_resume(), keď je korutín obnovený po pozastavení. Vypíše len správu, ktorá oznamuje, že korutín bol obnovený.

Nasledujúce riadky kódu definujú funkciu foo() coroutine. Vo vnútri foo() začneme vytlačením správy, ktorá hovorí, že korutín sa začal. Potom sa na pozastavenie korutíny použije co_await std::suspend_always{} a indikuje, že v ňom možno pokračovať neskôr. Príkaz co_return sa používa na dokončenie korutíny bez vrátenia akejkoľvek hodnoty.

Vo funkcii main() vytvoríme objekt „cr“ typu „ThisCorout“ volaním foo(). Tým sa vytvorí a spustí korutín. Potom sa vytlačí správa, že korutín bol vytvorený. Ďalej zavoláme wait_resume() na objekte „cr“ coroutine, aby sme obnovili jeho vykonávanie. Vo vnútri wait_resume() je vytlačená správa „The Coroutine is continue“. Nakoniec zobrazíme správu, ktorá oznamuje, že korutín je dokončený pred ukončením programu.

Keď spustíte tento program, výstup je takýto:

Príklad 2: Korutín s parametrami a výťažnosťou

Teraz, pre túto ilustráciu, poskytujeme kód, ktorý demonštruje použitie korutínov s parametrami a výnosom v C++ na vytvorenie správania podobného generátora na vytvorenie postupnosti čísel.

#include

#include

#include

štrukturovať NEWCoroutine {

štrukturovať p_type {

std :: vektor < int > hodnoty ;

NEWCoroutine get_return_object ( ) { vrátiť { } ; }

std :: suspend_always initial_suspend ( ) { vrátiť { } ; }

std :: suspend_always final_suspend ( ) nookrem { vrátiť { } ; }

neplatné unhandled_exception ( ) { }

neplatné return_void ( ) { }

std :: suspend_always výnos_hodnota ( int hodnotu ) {

hodnoty. push_back ( hodnotu ) ;

vrátiť { } ;

}

} ;

std :: vektor < int > hodnoty ;

štrukturovať iterátor {

std :: coroutine_handle <> chorus_handle ;

boolov operátor != ( konšt iterátor & iné ) konšt { vrátiť chorus_handle != iné. chorus_handle ; }

iterátor & operátor ++ ( ) { chorus_handle. pokračovať ( ) ; vrátiť * toto ; }

int operátor * ( ) konšt { vrátiť chorus_handle. sľúbiť ( ) . hodnoty [ 0 ] ; }

} ;

iterátor začať ( ) { vrátiť iterátor { std :: coroutine_handle < p_type >:: od_sľubu ( sľúbiť ( ) ) } ; }

koniec iterátora ( ) { vrátiť iterátor { nullptr } ; }

std :: coroutine_handle < p_type > sľúbiť ( ) { vrátiť
std :: coroutine_handle < p_type >:: od_sľubu ( * toto ) ; }

} ;

NEWKorutina generovať čísla ( ) {

ko_výnos 5 ;

ko_výnos 6 ;

ko_výnos 7 ;

}

int Hlavná ( ) {

NEWCoroutine nc = generovať čísla ( ) ;

pre ( int hodnotu : nc ) {

std :: cout << hodnotu << '' ;

}

std :: cout << std :: endl ;

vrátiť 0 ;

}

V predchádzajúcom kóde predstavuje štruktúra NEWCoroutine generátor založený na korutíne. Obsahuje vnorenú štruktúru „p_type“, ktorá slúži ako typ prísľubu pre korutín. Štruktúra p_type definuje funkcie, ktoré vyžaduje korutínny mechanizmus, ako napríklad get_return_object(), initial_suspend(), final_suspend(), unhandled_exception() a return_void(). Štruktúra p_type tiež obsahuje funkciu yield_value(int value), ktorá sa používa na získanie hodnôt z korutínu. Pridá zadanú hodnotu k vektoru hodnôt.

Štruktúra NEWCoroutine obsahuje členskú premennú std::vector s názvom „values“, ktorá predstavuje vygenerované hodnoty. Vnútri NEWCoroutine je vnorený iterátor štruktúr, ktorý umožňuje iterovať vygenerované hodnoty. Obsahuje coro_handle, čo je rukoväť korutíny a definuje operátory ako !=, ++ a * pre iteráciu.

Funkciu begin() používame na vytvorenie iterátora na začiatku coroutine získaním coro_handle z prísľubu p_type. Zatiaľ čo funkcia end() vytvára iterátor, ktorý predstavuje koniec coroutine a je skonštruovaný pomocou nullptr coro_handle. Potom sa funkcia sľub() použije na vrátenie typu prísľub vytvorením coroutine_handle z prísľubu p_type. Funkcia createNumbers() je korutín, ktorý poskytuje tri hodnoty – 5, 6 a 7 – pomocou kľúčového slova co_yield.

Vo funkcii main() sa vytvorí inštancia NEWCoroutine s názvom „nc“ vyvolaním korutínu generationNumbers(). Toto inicializuje korutín a zachytí jeho stav. Slučka „for“ založená na rozsahu sa používa na iteráciu hodnôt „nc“ a vytlačí sa každá hodnota, ktorá je oddelená medzerou pomocou std::cout.

Vygenerovaný výstup je nasledovný:

Záver

Tento článok demonštruje využitie korutínov v C++. Diskutovali sme o dvoch príkladoch. Pre prvú ilustráciu je základná korutína vytvorená v programe C++ pomocou funkcií korutín. Zatiaľ čo druhá demonštrácia sa uskutočnila s využitím korutínov s parametrami a podvolením sa generovania správania podobného generátoru na vytvorenie postupnosti čísel.